7.设计模式-ADAPTER(适配器)

一、模式定义与核心价值

适配器模式是一种结构型设计模式,其核心目标是解决接口不兼容问题,通过中间转换层让原本无法协同工作的类能够协作。其核心价值在于:

  1. 接口兼容:将旧系统接口转换为新系统所需的接口形态
  2. 复用解耦:无需修改现有代码即可复用遗留组件,降低系统耦合度
  3. 动态扩展:支持灵活添加新适配器,应对未来接口变更需求

工业级场景

  • 系统集成时对接第三方库接口(如支付网关对接不同银行API)
  • 旧系统升级时保留原有功能模块(如数据库驱动兼容不同版本)
  • 硬件设备接口转换(如USB转Type-C充电器)

二、模式组成与UML类图

核心角色

  1. Target(目标接口):客户端期望的接口规范(如USB充电接口
  2. Adaptee(被适配者):已存在但接口不兼容的类(如220V电源接口
  3. Adapter(适配器):实现接口转换的中间层(如充电头

UML类图

classDiagram
    class Target {
        <<interface>>
        +request()
    }

    class Adaptee {
        +specificRequest()
    }

    class Adapter {
        -adaptee: Adaptee
        +request()
    }

    Target <|.. Adapter
    Adapter --> Adaptee

    class ClassAdapter {
        +request()
    }

    Adaptee <|-- ClassAdapter
    Target <|.. ClassAdapter

说明

  • 对象适配器:通过组合方式持有Adaptee实例(左图)
  • 类适配器:通过多重继承实现接口转换(右图)

三、代码实现示例

场景1:电压转换适配器(对象适配器)
// 目标接口(USB充电标准)
interface USBCharger {
    void charge(int voltage);
}

// 被适配者(220V电源)
class PowerOutlet220V {
    void output220V() {
        System.out.println("输出220V交流电");
    }
}

// 适配器(转换220V为5V)
class PowerAdapter implements USBCharger {
    private PowerOutlet220V outlet;

    public PowerAdapter(PowerOutlet220V outlet) {
        this.outlet = outlet;
    }

    @Override
    public void charge(int voltage) {
        outlet.output220V();
        System.out.println("转换为" + voltage + "V直流电");
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        USBCharger charger = new PowerAdapter(new PowerOutlet220V());
        charger.charge(5); // 输出:220V交流电 → 5V直流电
    }
}
场景2:日志框架适配器(类适配器)
// 目标接口(系统日志标准)
interface Logger {
    void log(String message);
}

// 被适配者(第三方日志库)
class ThirdPartyLogger {
    void debug(String msg, Object... args) {
        System.out.printf("[DEBUG] " + msg + "%n", args);
    }
}

// 适配器(继承方式)
class LoggerAdapter extends ThirdPartyLogger implements Logger {
    @Override
    public void log(String message) {
        this.debug(message); // 调用父类方法
    }
}

// 使用示例
Logger logger = new LoggerAdapter();
logger.log("系统启动完成"); // 输出:[DEBUG] 系统启动完成

四、工业级源码应用

  1. Spring框架
    • **HandlerAdapter**:在Spring MVC中,DispatcherServlet通过适配器模式调用不同处理器(如@ControllerHttpRequestHandler),屏蔽底层差异
// 源码片段(简化版)
protected HandlerAdapter getHandlerAdapter(Object handler) {
for (HandlerAdapter ha : this.handlerAdapters) {
    if (ha.supports(handler)) return ha;
}
}
  1. JDBC驱动
    • **DriverManager**:通过适配器将不同数据库厂商的驱动接口(如MySQL、Oracle)统一为java.sql.Connection标准
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/db");
  1. Java集合框架
    • **Collections.unmodifiableList()**:通过适配器将可变List转换为不可变视图,保持接口兼容性
List<String> list = new ArrayList<>();
List<String> unmodifiable = Collections.unmodifiableList(list);
  1. Android开发
    • **RecyclerView.Adapter**:将数据集合适配为RecyclerView所需的视图类型,支持动态数据更新7****9
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
    // 实现数据到视图的适配
}

五、模式优缺点与选型建议

优势

  • 无缝集成:兼容新旧系统,降低重构成本
  • 灵活扩展:新增适配器不影响原有逻辑(开闭原则)
  • 代码复用:充分利用遗留代码资产

劣势

  • 复杂度上升:过多适配器会增加代码层级
  • 性能损耗:转换逻辑可能引入额外计算(如数据格式转换)

选型指南

  1. 优先对象适配器:避免继承带来的耦合问题(推荐组合方式)
  2. 慎用类适配器:仅适用于适配器与Adaptee存在明确继承关系的场景
  3. 结合工厂模式:通过工厂类管理多种适配器实例(如不同数据库驱动)

总结

适配器模式如同软件世界的“万能转接头”,通过巧妙的接口转换机制,解决了系统演进过程中的兼容性难题。在Java生态中,该模式已深度融入Spring、JDBC等主流框架,成为应对接口异构场景的基石技术。掌握适配器模式的关键在于理解转换逻辑的封装艺术,并能在实际开发中灵活选择对象适配器或类适配器实现方案。

posted @ 2025-04-12 10:41  雾里看花的少年  阅读(60)  评论(0)    收藏  举报