Java结构型模式---适配器模式
适配器模式基础概念
适配器模式是一种结构型设计模式,其核心思想是将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。适配器模式就像一个 "转换器",将两个不兼容的接口进行适配。
适配器模式的核心组件
- 目标接口 (Target) - 客户端所期望的接口
- 适配者类 (Adaptee) - 现有的、需要被适配的类
- 适配器类 (Adapter) - 连接目标接口和适配者类的桥梁,实现目标接口并包装适配者类
适配器模式的实现方式
适配器模式有两种主要实现方式:
- 类适配器 - 使用继承实现
- 对象适配器 - 使用组合实现
类适配器实现
类适配器通过继承适配者类并实现目标接口来实现适配。
// 目标接口
interface Target {void request();
}// 适配者类
class Adaptee {public void specificRequest() {System.out.println("Specific request from Adaptee");}
}// 类适配器
class ClassAdapter extends Adaptee implements Target {@Overridepublic void request() {// 调用适配者的方法specificRequest();}
}// 客户端代码
public class ClassAdapterClient {public static void main(String[] args) {Target target = new ClassAdapter();target.request(); // 输出: Specific request from Adaptee}
}
对象适配器实现
对象适配器通过持有适配者类的实例并实现目标接口来实现适配。
// 目标接口
interface Target {void request();
}// 适配者类
class Adaptee {public void specificRequest() {System.out.println("Specific request from Adaptee");}
}// 对象适配器
class ObjectAdapter implements Target {private Adaptee adaptee;public ObjectAdapter(Adaptee adaptee) {this.adaptee = adaptee;}@Overridepublic void request() {// 委托给适配者的方法adaptee.specificRequest();}
}// 客户端代码
public class ObjectAdapterClient {public static void main(String[] args) {Adaptee adaptee = new Adaptee();Target target = new ObjectAdapter(adaptee);target.request(); // 输出: Specific request from Adaptee}
}
双向适配器实现
双向适配器允许两个不兼容的接口可以互相适配。
// 目标接口
interface Target {void request();
}// 适配者接口
interface Adaptee {void specificRequest();
}// 具体目标类
class ConcreteTarget implements Target {@Overridepublic void request() {System.out.println("Normal request from ConcreteTarget");}
}// 具体适配者类
class ConcreteAdaptee implements Adaptee {@Overridepublic void specificRequest() {System.out.println("Specific request from ConcreteAdaptee");}
}// 双向适配器
class BidirectionalAdapter implements Target, Adaptee {private Target target;private Adaptee adaptee;public BidirectionalAdapter(Target target) {this.target = target;}public BidirectionalAdapter(Adaptee adaptee) {this.adaptee = adaptee;}@Overridepublic void request() {if (adaptee != null) {adaptee.specificRequest();}}@Overridepublic void specificRequest() {if (target != null) {target.request();}}
}// 客户端代码
public class BidirectionalAdapterClient {public static void main(String[] args) {// 适配 Adaptee 到 TargetAdaptee adaptee = new ConcreteAdaptee();Target targetAdapter = new BidirectionalAdapter(adaptee);targetAdapter.request(); // 输出: Specific request from ConcreteAdaptee// 适配 Target 到 AdapteeTarget target = new ConcreteTarget();Adaptee adapteeAdapter = new BidirectionalAdapter(target);adapteeAdapter.specificRequest(); // 输出: Normal request from ConcreteTarget}
}
适配器模式的应用场景
- 旧系统兼容 - 使旧系统的接口适配新系统的接口
- 第三方库集成 - 适配不同第三方库的接口
- 统一接口 - 将多个不同的类统一到一个共同的接口
- 数据格式转换 - 转换不同格式的数据
- 多重继承替代 - 在 Java 中实现类似多重继承的功能
类适配器与对象适配器的对比
特性 | 类适配器 | 对象适配器 |
---|---|---|
实现方式 | 继承适配者类并实现目标接口 | 持有适配者类的实例并实现目标接口 |
绑定程度 | 静态绑定,编译时确定 | 动态绑定,运行时确定 |
灵活性 | 低,只能适配一个特定的类 | 高,可以适配多个适配者类的子类 |
父类方法调用 | 可以直接调用适配者类的方法 | 需要通过适配者实例调用 |
实现复杂度 | 较低,结构简单 | 较高,需要维护适配者引用 |
适用场景 | 适配者类方法较少,不需要扩展 | 适配者类方法较多,需要灵活扩展 |
适配器模式的优缺点
优点:
- 提高复用性 - 可以复用现有类的功能
- 增加灵活性 - 可以在不修改原有代码的情况下适配新接口
- 解耦系统 - 将目标接口与适配者接口解耦
- 符合开闭原则 - 可以通过新增适配器类来扩展功能
缺点:
- 过多使用适配器会导致系统复杂 - 过多的适配器会使系统逻辑变得混乱
- 类适配器可能引入过多依赖 - 类适配器通过继承实现,可能导致依赖关系复杂
- 性能开销 - 适配器的调用可能带来额外的性能开销
使用适配器模式的注意事项
- 优先使用对象适配器 - 对象适配器比类适配器更灵活,更符合合成复用原则
- 不要过度使用适配器 - 如果可能,应重构接口而不是使用适配器
- 明确适配场景 - 确保确实需要适配,避免为了适配而适配
- 考虑双向适配器 - 在需要双向适配的场景中使用双向适配器
- 与其他模式结合 - 适配器模式可以与工厂模式、抽象工厂模式等结合使用
适配器模式是一种非常实用的设计模式,它通过引入一个适配器类来解决接口不兼容的问题,使得原本不能一起工作的类可以协同工作。在实际开发中,对象适配器更为常用,它提供了更灵活的适配方式。