适配器模式是一种结构型设计模式,用于将某个类的接口转换成客户端期望的另一个接口,使原本因接口不兼容而无法协作的类能够一起工作。本文从适配器模式的定义与核心角色出发,对比类适配器与对象适配器两种实现方式,结合 Java 代码演示其落地写法,并总结适用场景、优缺点以及与装饰器、外观等相似模式的辨析,帮助你在实际项目中判断何时该用、如何用好适配器模式。
一、适配器模式概述
1.1 什么是适配器模式
适配器模式(Adapter Pattern)属于结构型设计模式,它的核心思想是把一个类的接口转换成客户端所期待的另一种接口,从而让原本接口不兼容、无法协同工作的类可以一起工作。
1.2 生活中的类比
电源转接头、读卡器、Type-C 转 HDMI 线,都是适配器思想在现实中的体现:目标接口不变,中间加一层转换,让两端能够对接。
1.3 模式的核心角色
- 目标接口(Target):客户端期望使用的接口。
- 被适配者(Adaptee):已经存在、但接口不兼容的类。
- 适配器(Adapter):连接 Target 与 Adaptee 的桥梁,负责接口转换。
- 客户端(Client):只依赖 Target 接口进行调用。
二、适配器模式的两种实现方式
2.1 类适配器(继承实现)
通过继承被适配者并实现目标接口完成适配,结构简单,但受 Java 单继承限制,且会暴露被适配者的方法。
2.2 对象适配器(组合实现)
通过持有被适配者实例并实现目标接口完成适配,更灵活、耦合更低,是实际开发中的首选方案。
2.3 两种方式的对比
| 对比维度 | 类适配器 | 对象适配器 |
|---|---|---|
| 实现方式 | 继承 Adaptee | 组合 Adaptee |
| 灵活性 | 较低 | 较高 |
| 对被适配者的侵入 | 会暴露其方法 | 不暴露 |
| 推荐程度 | 一般 | 推荐 |
三、Java 代码实战
3.1 定义目标接口与被适配者
java
// 目标接口:客户端期望的充电方式
public interface TypeCCharger {
void chargeWithTypeC();
}
// 被适配者:已有的老式接口
public class MicroUsbCharger {
public void chargeWithMicroUsb() {
System.out.println("使用 Micro-USB 接口充电");
}
}
3.2 编写对象适配器
java
public class MicroUsbToTypeCAdapter implements TypeCCharger {
private final MicroUsbCharger microUsbCharger;
public MicroUsbToTypeCAdapter(MicroUsbCharger microUsbCharger) {
this.microUsbCharger = microUsbCharger;
}
@Override
public void chargeWithTypeC() {
System.out.println("适配器完成接口转换");
microUsbCharger.chargeWithMicroUsb();
}
}
3.3 客户端调用示例
java
public class Client {
public static void main(String[] args) {
TypeCCharger charger = new MicroUsbToTypeCAdapter(new MicroUsbCharger());
charger.chargeWithTypeC();
}
}
四、适用场景与优缺点
4.1 典型适用场景
- 需要复用已有类,但其接口与当前系统要求不一致。
- 对接第三方 SDK、老系统或遗留接口,不希望改动原有代码。
- 系统需要在多个不同接口之间做统一抽象。
4.2 优点
- 解耦目标接口与被适配者,符合开闭原则。
- 提高已有类的复用性,避免重复造轮子。
- 转换逻辑集中在一处,便于维护。
4.3 缺点
- 增加类的数量,过度使用会让系统结构变复杂。
- 类适配器受单继承限制,灵活性不足。
五、与相似模式的辨析及总结
5.1 适配器 vs 装饰器 vs 外观
- 适配器:改变接口,让不兼容的接口能够协作。
- 装饰器:不改变接口,动态增强对象功能。
- 外观:不改变接口,为子系统提供统一的高层入口。
5.2 实践建议
优先选择对象适配器;适配逻辑尽量保持单一职责,不要在适配器中混入业务处理;对第三方依赖做适配时,建议配合接口隔离,避免被适配者的细节泄漏到上层。
5.3 小结
适配器模式是解决接口不兼容问题的经典方案,理解其核心角色与两种实现方式,能帮助我们在系统集成、遗留系统改造等场景中做出更合理的设计选择。