Skip to content

适配器模式

基础概念

什么是适配器模式?

答案: 适配器模式(Adapter Pattern)将一个类的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作。

使用场景

  • 系统需要使用现有的类,但其接口不符合需求
  • 想要建立一个可以重复使用的类
  • 需要统一多个类的接口

优点

  • 提高类的复用性
  • 增加类的透明性
  • 灵活性好

缺点

  • 过多使用会使系统凌乱

类适配器

类适配器的实现?

答案:

java
// 目标接口
public interface Target {
    void request();
}

// 被适配者
public class Adaptee {
    public void specificRequest() {
        System.out.println("特殊请求");
    }
}

// 类适配器(通过继承)
public class ClassAdapter extends Adaptee implements Target {
    @Override
    public void request() {
        specificRequest();
    }
}

// 使用
Target target = new ClassAdapter();
target.request();

对象适配器

对象适配器的实现?

答案:

java
// 目标接口
public interface Target {
    void request();
}

// 被适配者
public class Adaptee {
    public void specificRequest() {
        System.out.println("特殊请求");
    }
}

// 对象适配器(通过组合)
public class ObjectAdapter implements Target {
    private Adaptee adaptee;

    public ObjectAdapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void request() {
        adaptee.specificRequest();
    }
}

// 使用
Adaptee adaptee = new Adaptee();
Target target = new ObjectAdapter(adaptee);
target.request();

推荐使用对象适配器,因为组合优于继承。

实际应用

日志适配器

答案:

java
// 目标接口:统一的日志接口
public interface Logger {
    void log(String message);
}

// 被适配者:Log4j
public class Log4jLogger {
    public void logMessage(String msg) {
        System.out.println("Log4j: " + msg);
    }
}

// 被适配者:Logback
public class LogbackLogger {
    public void writeLog(String msg) {
       ystem.out.println("Logback: " + msg);
    }
}

// Log4j适配器
public class Log4jAdapter implements Logger {
    private Log4jLogger log4j;

    public Log4jAdapter(Log4jLogger log4j) {
        this.log4j = log4j;
    }

    @Override
    public void log(String message) {
        log4j.logMessage(message);
    }
}

// Logback适配器
public class LogbackAdapter implements Logger {
    private LogbackLogger logback;

    public LogbackAdapter(LogbackLogger logback) {
        this.logback = logback;
    }

    @Override
    public void log(String message) {
        logback.writeLog(message);
    }
}

// 使用
Logger logger1 = new Log4jAdapter(new Log4jLogger());
logger1.log("使用Log4j记录日志");

Logger logger2 = new LogbackAdapter(new LogbackLogger());
logger2.log("使用Logback记录日志");

支付适配器

答案:

java
// 目标接口:统一的支付接口
public interface Payment {
    boolean pay(BigDecimal amount);
}

// 被适配者:支付宝SDK
public class AlipaySDK {
    public String sendPayment(double money) {
        System.out.println("支付宝支付: " + money);
        return "success";
    }
}

// 被适配者:微信SDK
public class WechatSDK {
    public int processPay(String amount) {
        System.out.println("微信支付: " + amount);
        return 0;  // 0表示成功
    }
}

// 支付宝适配器
public class AlipayAdapter implements Payment {
    private AlipaySDK alipay;

    public AlipayAdapter(AlipaySDK alipay) {
        this.alipay = alipay;
    }

    @Override
    public boolean pay(BigDecimal amount) {
        String result = alipay.sendPayment(amount.doubleValue());
        return "success".equals(result);
    }
}

// 微信适配器
public class WechatAdapter implements Payment {
    private WechatSDK wechat;

    public WechatAdapter(WechatSDK wechat) {
        this.wechat = wechat;
    }

    @Override
    public boolean pay(BigDecimal amount) {
        int result = wechat.processPay(amount.toString());
        return result == 0;
    }
}

// 使用
Payment payment1 = new AlipayAdapter(new AlipaySDK());
payment1.pay(new BigDecimal("100.00"));

Payment payment2 = new WechatAdapter(new WechatSDK());
payment2.pay(new BigDecimal("200.00"));

Spring中的适配器模式

HandlerAdapter?

答案:

Spring MVC中的HandlerAdapter就是适配器模式的应用。

java
// 处理器适配器接口
public interface HandlerAdapter {
    boolean supports(Object handler);
    ModelAndView handle(HttpServletRequest request,
                       HttpServletResponse response,
                       Object handler) throws Exception;
}

// Controller适配器
public class SimpleControllerHandlerAdapter implements HandlerAdapter {
    @Override
    public boolean supports(Object handler) {
        return (handler instanceof Controller);
    }

    @Override
    public ModelAndView handle(HttpServletRequest request,
                              HttpServletResponse response,
                             t handler) throws Exception {
        return ((Controller) handler).handleRequest(request, response);
    }
}

// RequestMapping适配器
public class RequestMappingHandlerAdapter implements HandlerAdapter {
    @Override
    public boolean supports(Object handler) {
        return (handler instanceof HandlerMethod);
    }

    @Override
    public ModelAndView handle(HttpServletRequest request,
                              HttpServletResponse response,
                              Object handler) throws Exception {
        return ((HandlerMethod) handler).invokeForRequest(request, response);
    }
}

练习题

  1. 类适配器和对象适配器的区别?
  2. 适配器模式和装饰器模式的区别?
  3. 什么时候使用适配器模式?
  4. 如何适配多个不兼容的接口?
  5. Spring MVC的HandlerAdapter如何工作?

Released under the MIT License.