跳至正文
来两杯美式
返回

设计模式之适配器模式:让不兼容的接口协同工作

By 来两杯美式
发布于

这是 2020 年 3 月整理的设计模式专题第四篇。适配器模式是结构型模式里最贴近生活的——手机充电器的电源适配器就是活生生的例子。本文用它讲清适配器的本质:如何在不改源码的情况下,让接口不兼容的类协同工作。

简单说明

适配器模式(Adapter Pattern):将一个类的接口转换成客户期望的另一个接口,使原本不兼容的接口可以兼容一起工作

核心思想:不改动已有类的代码,也不改动客户端代码,中间加一层”转换器”。

简单代码实现

模拟将 220V 交流电转换为 5V 直流电的电源适配器。

/**
 * 描述:220V 交流电(被适配者)
 */
public class AC220 {
    public int outPut220V() {
        return 220;
    }
}

/**
 * 描述:5V 直流(适配目标)
 */
public interface DC5 {
    int outPut5V();
}

/**
 * 描述:电源适配器(对象适配器实现)
 */
public class PowerAdapter implements DC5 {
    AC220 ac220 = new AC220();

    @Override
    public int outPut5V() {
        return ac220.outPut220V() / 44;
    }
}

/**
 * 描述:适配器测试类
 */
public class AdapterTest {
    public static void main(String[] args) {
        DC5 dc5 = new PowerAdapter();
        System.out.println(dc5.outPut5V());
    }
}

角色对应

对象适配器 vs 类适配器

上面的实现是对象适配器:适配器组合被适配者(PowerAdapter 内部 new AC220())。

类适配器则通过继承实现:适配器继承 AC220,直接调用 super 的方法,而不用在适配器中 new。

/**
 * 描述:类适配器:继承 AC220,直接调用父类方法
 */
public class PowerAdapter extends AC220 implements DC5 {
    @Override
    public int outPut5V() {
        return outPut220V() / 44;
    }
}
对比项对象适配器类适配器
实现方式组合(持有被适配者实例)继承(extends 被适配者)
耦合度低,更灵活高,受继承限制
应用更常用(优先组合)较少用

适用场景与优缺点

适用场景

优点

缺点

现实中的应用

场景说明
电源适配器220V → 5V,最直观的比喻
InputStreamReader / OutputStreamWriter字节流 → 字符流的适配器
JDBC 驱动不同数据库方言统一成 JDBC 接口
Spring MVC HandlerAdapter适配不同类型的 Controller(@Controller、HttpRequestHandler)
支付系统支付宝/微信/银联统一成一套支付接口

小结


分享这篇文章:
通过邮件分享这篇文章✓ 链接已复制
查看系列全部文章
  1. 01.软件设计原则:SOLID + KISS / YAGNI / LOD 全景
  2. 02.设计模式之原型模式,及深浅拷贝
  3. 03.设计模式之工厂模式:简单工厂、工厂方法与抽象工厂
  4. 04.设计模式之建造者模式:复杂对象的组装艺术
  5. 05.设计模式之适配器模式:让不兼容的接口协同工作
  6. 06.设计模式之桥接模式:抽象与实现分离,各自独立变化
  7. 07.设计模式之装饰者模式:动态增强,比继承更有弹性
  8. 08.设计模式之代理模式:静态代理与 JDK 动态代理
  9. 09.设计模式之外观模式:统一门面,简化子系统调用
  10. 10.设计模式之享元模式:共享细粒度对象,降低内存占用
  11. 11.设计模式之策略模式:算法家族,自由切换
  12. 12.设计模式之模板方法模式:固定骨架,可变步骤
  13. 13.设计模式之观察者模式:一对多依赖,状态变更自动通知
  14. 14.设计模式之责任链模式:请求逐级传递,动态组合处理者
  15. 15.设计模式之状态模式:状态变,行为变
  16. 16.设计模式之迭代器模式:不暴露内部实现,顺序访问集合

上一篇
DDD 复杂业务系统设计(七):分层架构,你的“业务代码”应该待在哪一层
下一篇
DDD 复杂业务系统设计(六):领域事件,让“作业提交”自动触发批改进度