目录

适配器模式 (Adapter Pattern)

将不兼容的接口转换为兼容的接口,实现系统间的协同工作

概述

适配器模式是一种结构型设计模式,它允许将一个类的接口转换成客户端希望的另一个接口。适配器让原本接口不兼容的类可以合作无间。

适用场景

  • 使用现有类,但其接口不符合需求
  • 需要统一多个类的接口
  • 系统需要与第三方库集成
  • 旧系统升级兼容

实现方式

1. 类适配器(继承)

// 目标接口
public interface MediaPlayer {
    void play(String audioType, String fileName);
}

// 被适配者
public class AdvancedMediaPlayer {
    public void playMp4(String fileName) {
        System.out.println("播放 MP4: " + fileName);
    }
    
    public void playVlc(String fileName) {
        System.out.println("播放 VLC: " + fileName);
    }
}

// 类适配器(继承)
public class MediaAdapter extends AdvancedMediaPlayer implements MediaPlayer {
    @Override
    public void play(String audioType, String fileName) {
        if ("mp4".equalsIgnoreCase(audioType)) {
            playMp4(fileName);
        } else if ("vlc".equalsIgnoreCase(audioType)) {
            playVlc(fileName);
        }
    }
}

// 使用
MediaPlayer player = new MediaAdapter();
player.play("mp4", "movie.mp4");

2. 对象适配器(组合)

// 对象适配器(推荐)
public class MediaAdapter implements MediaPlayer {
    private AdvancedMediaPlayer advancedPlayer;
    
    public MediaAdapter(AdvancedMediaPlayer player) {
        this.advancedPlayer = player;
    }
    
    @Override
    public void play(String audioType, String fileName) {
        if ("mp4".equalsIgnoreCase(audioType)) {
            advancedPlayer.playMp4(fileName);
        } else if ("vlc".equalsIgnoreCase(audioType)) {
            advancedPlayer.playVlc(fileName);
        }
    }
}

实际应用:支付适配器

// 统一的支付接口
public interface PaymentProcessor {
    void processPayment(BigDecimal amount);
    void refund(String transactionId);
}

// 支付宝 SDK
public class AlipaySDK {
    public void pay(double amount) {
        System.out.println("支付宝支付: " + amount);
    }
    
    public void doRefund(String id) {
        System.out.println("支付宝退款: " + id);
    }
}

// 微信支付 SDK
public class WechatPaySDK {
    public void makePayment(BigDecimal amount) {
        System.out.println("微信支付: " + amount);
    }
    
    public void returnMoney(String orderId) {
        System.out.println("微信退款: " + orderId);
    }
}

// 支付宝适配器
public class AlipayAdapter implements PaymentProcessor {
    private AlipaySDK alipay = new AlipaySDK();
    
    @Override
    public void processPayment(BigDecimal amount) {
        alipay.pay(amount.doubleValue());
    }
    
    @Override
    public void refund(String transactionId) {
        alipay.doRefund(transactionId);
    }
}

// 微信适配器
public class WechatPayAdapter implements PaymentProcessor {
    private WechatPaySDK wechatPay = new WechatPaySDK();
    
    @Override
    public void processPayment(BigDecimal amount) {
        wechatPay.makePayment(amount);
    }
    
    @Override
    public void refund(String transactionId) {
        wechatPay.returnMoney(transactionId);
    }
}

// 支付服务
@Service
public class PaymentService {
    private final Map<String, PaymentProcessor> processors = new HashMap<>();
    
    public PaymentService() {
        processors.put("alipay", new AlipayAdapter());
        processors.put("wechat", new WechatPayAdapter());
    }
    
    public void pay(String type, BigDecimal amount) {
        PaymentProcessor processor = processors.get(type);
        if (processor == null) {
            throw new IllegalArgumentException("不支持的支付方式");
        }
        processor.processPayment(amount);
    }
}

框架中的应用

Spring MVC HandlerAdapter

// Spring 使用适配器模式适配不同类型的 Controller
public interface HandlerAdapter {
    boolean supports(Object handler);
    ModelAndView handle(HttpServletRequest request, 
                        HttpServletResponse response, 
                        Object handler);
}

// 适配不同的 Controller 类型
public class SimpleControllerHandlerAdapter implements HandlerAdapter {
    @Override
    public boolean supports(Object handler) {
        return handler instanceof Controller;
    }
    
    @Override
    public ModelAndView handle(HttpServletRequest request,
                               HttpServletResponse response,
                               Object handler) {
        return ((Controller) handler).handleRequest(request, response);
    }
}

// 适配注解 Controller
public class RequestMappingHandlerAdapter implements HandlerAdapter {
    // 处理 @Controller + @RequestMapping
}

Java IO 适配器

// InputStreamReader 是字节流到字符流的适配器
InputStream inputStream = new FileInputStream("file.txt");
Reader reader = new InputStreamReader(inputStream, "UTF-8");

// OutputStreamWriter 是字符流到字节流的适配器
Writer writer = new OutputStreamWriter(System.out);

Arrays.asList()

// 数组转列表的适配器
String[] array = {"a", "b", "c"};
List<String> list = Arrays.asList(array); // 适配器视图

新旧系统兼容

// 旧的用户系统接口
public interface OldUserService {
    String findUserName(int userId);
}

// 新的用户系统接口
public interface NewUserService {
    User findById(Long userId);
}

// 新的实现
public class NewUserServiceImpl implements NewUserService {
    @Override
    public User findById(Long userId) {
        return new User(userId, "username");
    }
}

// 适配器:让新系统兼容旧接口
@Component
public class UserServiceAdapter implements OldUserService {
    @Autowired
    private NewUserService newUserService;
    
    @Override
    public String findUserName(int userId) {
        User user = newUserService.findById((long) userId);
        return user != null ? user.getName() : null;
    }
}

优缺点

优点缺点
解耦目标类和被适配者增加系统复杂度
复用现有类过多适配器使代码难以理解
扩展性好

总结

适配器模式是解决接口不兼容问题的有效手段。对象适配器比类适配器更灵活(通过组合而非继承),是更推荐的方式。在集成第三方库、系统升级等场景中非常实用。