欢迎光临
我们一直在努力

设计模式-适配器模式

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

它的核心思想是不修改现有代码,通过引入一个中间“适配器”角色,充当接口之间的“翻译官”或“转换头”,解决不同组件之间的兼容性问题。

优缺点

优点

  • 优秀的复用性与兼容性: 无需修改现有的老旧代码,就能让原本不兼容的类在新的业务逻辑中协同工作。
  • 符合开闭原则(OCP): 增加新的适配器无需修改原有接口或已有类,只需新增适配类即可。
  • 解耦业务逻辑与接口转换: 将复杂的格式转换、参数映射等细节封装在适配器内部,客户端调用更简洁干净。

缺点

  • 增加系统复杂度: 过多使用适配器会让代码结构显得零乱(明明调用的是 A 接口,底层却跑到了 B 类的逻辑),增加阅读和调试难度。
  • 类适配器受限于单继承: 在 Java 等不支持多继承的语言中,类适配器模式一次只能适配一个源类,使用上有局限性。

举个例子

手机充电需要 5V 直流电,但墙上的插座提供的是 220V 交流电。手机不能直接插 220V 插座(接口不兼容,强插会烧毁硬件),我们需要一个电源适配器(Charger Adapter),将 220V 的电压转换为 5V。

1. 源接口/现存类(Adaptee):220V 交流电源

// 现有的墙壁插座,只能输出 220V 电压
public class Output220V {
public int output220V() {
System.out.println("输出交流电:220V");
return 220;
}
}

2. 目标接口(Target):手机需要的 5V 接口

// 手机期望的标准充电接口
public interface Target5V {
int output5V();
}

3. 适配器类(Adapter):电源适配器

利用对象适配器(内部持有一份 Output220V 的引用),将 220V 转化为 5V。

public class PowerAdapter implements Target5V {
private Output220V output220V; // 组合源对象

public PowerAdapter(Output220V output220V) {
this.output220V = output220V;
}

@Override
public int output5V() {
// 获取原始 220V 电压
int src = output220V.output220V();
// 适配器进行变压加工逻辑
int dst = src / 44;
System.out.println("适配器转换:将 " + src + "V 变压为 " + dst + "V 直流电");
return dst;
}
}

4. 客户端调用(Client):手机充电

public class Phone {
// 手机充电只认 Target5V 接口
public void charge(Target5V target5V) {
if (target5V.output5V() == 5) {
System.out.println("电压正常,手机开始充电!");
} else {
System.out.println("电压不匹配,无法充电!");
}
}
}

public class User {
public static void main(String[] args) {
Phone phone = new Phone();

// 现有资源:墙上的 220V 插座
Output220V wallSocket = new Output220V();

// 中间件:插上电源适配器
Target5V adapter = new PowerAdapter(wallSocket);

// 手机连接适配器进行充电
phone.charge(adapter);
}
}

Plaintext

输出交流电:220V
适配器转换:将 220V 变压为 5V 直流电
电压正常,手机开始充电!

适配器模式的实现方式

  • 对象适配器(最推荐): 适配器类持有一个源对象的引用(采用组合而非继承)。灵活性高,符合“多用组合,少用继承”的设计原则。
  • 类适配器: 适配器类同时继承源类(Adaptee)并实现目标接口(Target)。依赖继承机制,会导致接口暴露过多源类方法,且在单继承语言中无法同时适配多个源类。
  • 接口适配器(缺省适配器/Default Adapter): 当目标接口定义了非常多的抽象方法,而子类只需要实现其中一部分时,用一个抽象类先空实现该接口的所有方法,具体的业务子类只需继承该抽象类并重写感兴趣的方法即可(常见于 GUI 事件监听器,如 WindowAdapter)。
  • 适用场景

    • 系统升级与旧代码重构: 需要复用现有的老代码或第三方模块,但其方法签名/接口不符合新系统的标准接口要求。
    • 第三方 SDK 接入统一包装: 例如系统中要集成多家支付 SDK(微信、支付宝、银联),各家的接口命名与参数完全不同,可以通过适配器统一封装为系统自身的 PayService 规范。
    • 跨平台/跨框架兼容: 数据库驱动(JDBC Driver)、不同日志框架(SLF4J 对 Log4j/JUL 的适配)等桥接转换场景。
    赞(0)
    未经允许不得转载:171主机测评 » 设计模式-适配器模式
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址