适配器和组合 Adapter and Composite Patterns
适配器模式
- 模式动机
- 现有的接口需要转化为客户类期望的接口,从而保证现有类的重用
- 定义一个包装类,包装不兼容接口的对象,这个包装类就是适配器,包装的对象是适配者
- 适配器提供客户类需要的接口,适配器的实现就是把客户类的请求转化为对适配者的相应接口的调用,当客户类调用适配器的方法时,在适配器内部将调用适配者类的方法。因此,适配器可以使接口不兼容而不能交互的类可以一起工作
- 模式定义
- 将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,别名包装器
- 模式结构
- Target 目标抽象类
- Adapter 适配器类
- Adaptee 适配者类
- Client客户类
对象适配器

类适配器

类适配器通过“继承适配者类”来复用其功能,对象适配器通过“持有适配者对象”来复用其功能;前者是 extends,后者是组合 has-a
- 模式优缺点
- 共有优点
- 将目标类和适配者类解耦
- 增加了类的透明性和复用性
- 这里的透明指adapter中能看到具体用的哪个Adaptee类
- 灵活性和扩展性好
- 类适配器独有优点
- 由于适配器类是适配者类的子类(适用于类适配器,对象适配器不是子类),因此可以在适配器类中置换一些适配者的方法,使得适配器的灵活性更强
- 对象适配器独有优点
- 同一个适配器可以把适配者类和它的子类都适配到目标接口
- 类适配器独有缺点
- 对于不支持多重继承的语言,一次最多只能适配一个适配者类,目标抽象类只能为抽象类,不能为具体类,其使用有一定局限性,不能将适配者类和它的子类都适配到目标接口
- 对象适配器独有缺点
- 与类适配器模式相比,要想置换适配者类的方法就不容易(类适配器模式可以直接重写方法,对象适配器就得先做一个适配者类的子类)
- 共有优点
- 模式适用环境
- 系统需要使用现有的类,而这些类的接口不符合系统的需要
- 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些将来可能引进的类一起工作
- 模式应用
- JDBC与各个数据库引擎接口之间的适配器软件
- 模式扩展
- 默认适配器模式
- 先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求
- 适用于一个接口不想使用其所有方法的情况
- 也称为单接口适配器模式
- 双向适配器
- 对象适配器的使用过程中,如果在适配器中同时包含对目标类和适配者类的引用,适配者可以通过它调用目标类中的方法,目标类也可以通过它调用适配者类中的方法
- 默认适配器模式

组合模式
- 模式动机
- 对于树形结构,当容器对象的某一个方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员对象并调用执行(递归调用)
- 由于容器对象和叶子对象在功能上的区别,在使用这些对象的客户端代码中必须有区别地对待容器对象和叶子对象,而实际上大多数情况下客户端希望一致地处理它们,因为对于这些对象的区别对待将会使得程序非常复杂
- 组合模式描述了如何将容器对象和叶子对象进行递归组合,使得用户在使用时无须对它们进行区分,可以一致地对待容器对象和叶子对象
- 模式定义
- 组合多个对象形成树形结构以“整体-部分”的结构层次。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性
- 又称为整体-部分模式,属于对象的结构模式,它将对象组织到树结构中,可以用来描述整体与部分的关系
- 模式结构
- Component 抽象构件
- Leaf 叶子构件
- Composite 容器构件
- Client 客户类

- 模式分析
- 定义了一个抽象构件类,既可以代表叶子,又可以代表容器,而客户端针对该抽象构件类进行编程,从而统一处理
- 容器对象与抽象构件类之间建立一个聚合关联关系,在容器对象中既可以包含叶子,也可以包含容器,以此实现递归组合,形成一个树形结构
- 模式实例
- 文件浏览
- 模式优缺点
- 优点
- 清楚地定义分层次的复杂对象,表示对象的全部或部分层次,使得增加新构件也更容易
- 客户端调用简单,客户端可以一致的使用组合结构或其中单个对象
- 定义了包含叶子对象和容器对象的类层次结构,可以形成复杂的树形结构
- 更容易在组合体内加入对象构件,客户端不必因为加入了新的对象而更改原有的代码
- 优点
- 缺点
- 使设计变得更加抽象,对象的业务规则如果很复杂,则实现组合模式具有很大挑战性,而且不是所有的方法都与叶子对象子类都有关联
- 增加新构件时可能会产生一些问题,很难对容器中的构件类型进行限制
- 模式适用环境
- 需要表示一个对象整体或部分层次,在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,可以一致地对待它们
- 让客户能够忽略不同对象层次的变化,客户端可以针对抽象构件编程,无须关心对象层次结构的细节
- 对象的结构是动态的并且复杂程度不一样,但客户需要一致地处理它们
- 模式应用
- XML文档解析
- 操作系统的目录结构
- jdk的AWT/Swing
- 模式扩展
- 透明组合模式

- 安全组合模式

- 透明组合模式
英文补充 English Supplement
Adapter Pattern 适配器模式
英文定义:
Convert the interface of a class into another interface clients expect.
Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.
中文意思:
将一个类的接口转换成客户期望的另一个接口。适配器使原本由于接口不兼容而不能一起工作的类可以协同工作。
别名:
Wrapper
包装器
核心术语:
| English | 中文 | 说明 |
|---|---|---|
| Target | 目标接口 / 目标抽象类 | 客户端期望使用的接口 |
| Adapter | 适配器 | 负责接口转换 |
| Adaptee | 适配者 | 已有类,接口不符合客户端期望 |
| Client | 客户端 | 通过 Target 使用功能 |
| request | 请求方法 | Target 中定义的方法 |
| specificRequest | 特定请求方法 | Adaptee 中已有的方法 |
关键句:
The adapter translates the client's request into a call on the adaptee.
适配器把客户端请求转换为对适配者方法的调用。
Class Adapter vs Object Adapter
| Type | 中文 | 实现方式 | 特点 |
|---|---|---|---|
| Class Adapter | 类适配器 | inheritance 继承 | Adapter 继承 Adaptee 并实现 Target |
| Object Adapter | 对象适配器 | composition 组合 | Adapter 持有 Adaptee 对象 |
考试常用表达:
- A class adapter uses inheritance.
- An object adapter uses composition.
- Object adapter is often more flexible because it can adapt an adaptee and its subclasses.
- Class adapter may override adaptee’s behavior, but it is limited by single inheritance in Java.
一句话记忆:
Adapter changes an interface, not the original class.
适配器改变的是对外接口,不是原有类本身。
Default Adapter Pattern 缺省适配器模式
英文:
Default Adapter Pattern provides default empty implementations for all methods in an interface,
so subclasses only need to override the methods they care about.
中文:
缺省适配器为接口中的所有方法提供默认空实现,让子类只覆盖自己关心的方法。
适用情况:
- 一个接口方法很多
- 子类只想实现其中几个方法
- 不希望每个子类都被迫写一堆空方法
Two-way Adapter 双向适配器
Two-way Adapter
双向适配器
双向适配器同时持有 Target 和 Adaptee 的引用,使两边都可以通过适配器调用对方的方法。
Composite Pattern 组合模式
英文定义:
Compose objects into tree structures to represent part-whole hierarchies.
Composite lets clients treat individual objects and compositions of objects uniformly.
中文意思:
将对象组合成树形结构来表示“部分-整体”的层次结构。组合模式使客户端可以一致地处理单个对象和对象组合。
别名:
Part-Whole Pattern
整体-部分模式
核心术语:
| English | 中文 | 说明 |
|---|---|---|
| Component | 抽象构件 | 叶子和容器的公共接口 |
| Leaf | 叶子构件 | 没有子节点的对象 |
| Composite | 容器构件 | 可以包含 Leaf 或 Composite |
| Client | 客户端 | 针对 Component 编程 |
| child | 子构件 | 容器中包含的对象 |
| recursive composition | 递归组合 | 容器中继续包含容器 |
关键句:
Clients can treat leaves and composites uniformly.
客户端可以一致地处理叶子对象和容器对象。
Transparent Composite vs Safe Composite
| Type | 中文 | 特点 | 代价 |
|---|---|---|---|
| Transparent Composite | 透明组合模式 | add/remove/getChild 等方法放在 Component 中 |
Leaf 也会拥有不适合自己的方法 |
| Safe Composite | 安全组合模式 | 管理子构件的方法只放在 Composite 中 | 客户端不能完全一致地处理 Leaf 和 Composite |
考试表达:
- Transparent Composite emphasizes uniformity.
- Safe Composite emphasizes type safety.
- Composite Pattern is suitable for tree structures such as file systems, XML documents, and GUI component hierarchies.
Adapter 和 Composite 快速区分
| Pattern | 解决什么问题 | 关键词 |
|---|---|---|
| Adapter | 接口不兼容 | interface conversion |
| Composite | 整体和部分希望一致处理 | part-whole hierarchy |
高频英文术语 Glossary
| English Term | 中文 |
|---|---|
| Structural Pattern | 结构型模式 |
| Adapter Pattern | 适配器模式 |
| Wrapper | 包装器 |
| Target | 目标接口 |
| Adapter | 适配器 |
| Adaptee | 适配者 |
| incompatible interface | 不兼容接口 |
| class adapter | 类适配器 |
| object adapter | 对象适配器 |
| inheritance | 继承 |
| composition | 组合 |
| Default Adapter Pattern | 缺省适配器模式 |
| Two-way Adapter | 双向适配器 |
| Composite Pattern | 组合模式 |
| Component | 抽象构件 |
| Leaf | 叶子构件 |
| Composite | 容器构件 |
| part-whole hierarchy | 整体-部分层次结构 |
| tree structure | 树形结构 |
| recursive composition | 递归组合 |
| transparent composite | 透明组合 |
| safe composite | 安全组合 |