23种设计模式之适配器模式

68 阅读3分钟

1. 什么是适配器模式

适配器模式(Adapter Pattern)是 GoF 23种设计模式中结构型设计模式之一,其核心思想是将一个类的接口转换成客户端所期望的另一个接口 ,从而使原本由于接口不兼容而不能一起工作的类可以协同工作。 适配器模式就像现实中的电源适配器:比如你的笔记本是美标插头,但中国插座是国标,就需要一个“适配器”来转换插头形状,使设备能正常工作。

在软件中,适配器模式让不兼容的接口变得兼容

2.为什么需要适配器模式

在软件开发中,经常遇到以下情况:

  • 已有一个功能完善的类(如第三方库、遗留系统组件),但它的接口与当前系统要求的接口不一致
  • 不能或不希望修改原有类的代码(比如没有源码、修改成本高、违反开闭原则)。
  • 需要复用已有组件,但又必须满足新的接口规范。

此时,直接使用会报错或逻辑不通。适配器模式提供了一种非侵入式的解决方案:通过新增一个“适配器”类来桥接新旧接口,实现无缝集成。

3. 角色与UML

classDiagram
    class Client {
        +main()
    }

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

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

    class Adaptee {
        +specificRequest()
    }

    Client --> Target : uses
    Adapter ..|> Target : implements
    Adapter --> Adaptee : delegates to
类 / 接口模式中的角色作用与职责
Target目标接口定义客户端所期望的标准接口。客户端通过该接口调用服务,无需关心具体实现是原生类还是适配后的类。
Adaptee被适配者已存在的、具有所需功能但接口与 Target 不兼容的类。通常来自第三方库、遗留系统或不可修改的组件。
Adapter适配器实现 Target 接口,并内部持有 Adaptee 的实例(对象适配器)或继承 Adaptee(类适配器),负责将 Target 接口的方法调用转换为对 Adaptee 的调用,起到“接口翻译”作用。
Client客户端使用 Target 接口的调用方。它只依赖于目标接口,对适配器和被适配者的存在完全透明,从而实现解耦。

4. Java代码示例

1、目标接口(Target):新手机期望的充电接口(USB-C)

interface USB_C_Charger {
    void chargeWithUSB_C();
}

2、被适配者(Adaptee):老充电器(只有 Micro-USB)

class OldCharger {
    public void chargeWithMicroUSB() {
        System.out.println("🔋 使用 Micro-USB 充电中...");
    }
}

3、适配器(Adapter):把 Micro-USB 转成 USB-C

class ChargerAdapter implements USB_C_Charger {
    private OldCharger oldCharger; // 持有老充电器

    public ChargerAdapter(OldCharger oldCharger) {
        this.oldCharger = oldCharger;
    }

    @Override
    public void chargeWithUSB_C() {
        System.out.println("🔌 适配器:将 USB-C 请求转为 Micro-USB...");
        oldCharger.chargeWithMicroUSB(); // 委托给老充电器
    }
}

4、客户端(Client)

public class Client {
    public static void main(String[] args) {
        OldCharger oldCharger = new OldCharger();           // 老充电器
        USB_C_Charger adapter = new ChargerAdapter(oldCharger); // 适配器包装
        adapter.chargeWithUSB_C(); // 成功用老充电器给新手机充电!
    }
}

运行结果

🔌 适配器:将 USB-C 请求转为 Micro-USB...
🔋 使用 Micro-USB 充电中...

5. 优缺点

优点:

  • 提高复用性:无需修改现有类即可复用其功能。
  • 解耦:客户端只依赖 Target 接口,与 Adaptee 解耦。
  • 符合开闭原则:对扩展开放(加适配器),对修改关闭(不改 Adaptee)。
  • 透明性好:客户端无需知道背后使用的是适配器还是原生实现。

缺点:

  • 增加系统复杂度:每种不兼容都需要一个适配器,适配器过多会使代码难以维护。
  • 类适配器受限:在 Java 等单继承语言中无法通过继承实现多适配。

6. 典型应用

  • Spring MVC: 其中的 HandlerAdapter 就是适配器模式的体现:它将不同类型的 Controller(如注解式、实现 Controller 接口等)适配为统一的处理流程。
  • 日志框架整合:应用使用 SLF4J(Target),底层可能是 Log4j、Java Util Logging(Adaptee),SLF4J 提供了对应的适配器桥接。

一句话总结:适配器模式通过一个“转接头”类,将不兼容的接口转换成客户端期望的接口,让新旧系统或组件能够无缝协作。