一、引言
在前五篇博客中中,我们聚焦“创建型模式”,探讨了如何从内部构建和初始化对象。今天开启“结构型模式”篇章,其关注点在于如何组合多个对象以形成更灵活、可扩展的系统结构。一共七种模式:
- 适配器(Adapter)、
- 桥接(Bridge)、
- 组合(Composite)、
- 装饰(Decorator)、
- 外观(Facade)、
- 享元(Flyweight)
- 代理(Proxy)
首先我们聚焦最常用的适配器模式。
二、模式原理分析
定义:将一个类的接口转换为客户期望的另一个接口,使得原本因接口不兼容而无法协同的两个类能够一起工作。
- 目标(Target):客户期望使用的抽象接口或抽象类。
- 适配器(Adapter):继承或实现目标接口,在内部持有对“具体适配者”的引用,负责转换调用。
- 具体适配者(Adaptee):已有的、接口不符合目标接口的类或服务。
+----------------+ +----------------+ +-----------------+
| Client |--uses->| Target |<--+ | Adaptee |
+----------------+ +----------------+ | +-----------------+
| ▲
+---holds-+
Adapter
三、代码示例解析
// 目标抽象
public abstract class TargetAbstraction {
public abstract String filter(String str);
}
// 具体实现(原有功能)
public class TargetAbstractionImpl extends TargetAbstraction {
@Override
public String filter(String str) {
return str.replaceAll("a","A");
}
}
// 具体适配者(接口不匹配)
public class OtherClass {
public String replace(String str) {
return str.replaceAll("<","[");
}
public void preCheck(String str) { /* … */ }
}
// 适配器
public class Adapter extends TargetAbstraction {
private OtherClass otherClass = new OtherClass();
@Override
public String filter(String str) {
otherClass.preCheck(str); // 扩展前置校验
return otherClass.replace(str); // 调用适配者方法
}
}
- Adapter 继承自 TargetAbstraction,对外提供
filter()
;内部委托 OtherClass 实现真正的逻辑,并可在前后增加新功能。
四、原理总结
适配器模式封装了三点核心变化:
- 适配者可有任意不兼容接口;
- 客户只感知目标接口,实际调用多个接口;
- 适配器与适配者通过组合/继承引入灵活性。
其本质是“在既有接口外层包一层转换层”,可无限扩展。
五、使用场景
- 接口不可修改:如跨团队或第三方库接口;
- 接口功能老旧:需兼顾新旧功能;
- 统一不同接口:多个相似但不一致的类;
- 过渡升级:作为旧接口到新接口的桥梁;
- 外部系统依赖:调用第三方 API;
- 数据格式/协议转换。
六、优缺点
优点
- 解耦目标与适配者,实现代码复用;
- 透明性高,客户端不受影响;
- 符合里氏替换与开闭原则;
- 可统一多个不同接口。
缺点
- 一次只支持一个继承目标(Java 单继承限制);
- 适配层过多易臃肿;
- 多适配器依赖会导致链条维护困难。
七、实际案例
- Type-C 扩展坞:将笔记本的 Type-C 转换为 HDMI、USB、网口等接口。
- Java I/O:
InputStreamReader
将InputStream
转为Reader
,供BufferedReader
使用,即现实中的 Adapter。
八、总结
适配器模式能在不改动原接口的前提下,快速兼容并扩展功能,但应谨防过度嵌套与臃肿。