Appearance
组合模式(Composite Pattern)
1. 官方定义
"Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly."
—— 《Design Patterns: Elements of Reusable Object-Oriented Software》(GoF, 1994)
核心:将对象组合成树形结构以表示“部分-整体”层次结构,使客户端对单个对象和组合对象的使用具有一致性。
ViewGroup 是 View 的子类,并且 ViewGroup 是一个 View 的容器,也就是说 ViewGroup 可以包含若干个的 ViewGroup 或者 View。 文件夹包含若干个文件夹和文件,也适合组合模式。
2. 模式解释
核心思想
- 统一接口:叶子节点(单个对象)和容器节点(组合对象)实现相同接口(如
Component
)。 - 递归结构:容器节点可嵌套其他容器或叶子节点(如文件夹包含文件和子文件夹)。
- 透明性:客户端无需区分处理单个对象或组合对象(统一调用
operation()
)。
典型结构
plaintext
|<<Component>>|
FileSystemItem
△
| implements
┌───────┴───────┐
| |
File Folder
△
| contains → FileSystemItem
优点
- 简化客户端代码:统一处理简单和复杂元素(如递归计算文件夹总大小)。
- 高扩展性:新增元素类型不影响现有结构(如添加
SymLink
符号链接)。 - 自然建模:直接映射真实世界的树形结构(如组织架构、XML DOM)。
缺点
- 接口过度泛化:叶子节点被迫实现无意义的方法(如
File
实现addChild()
)。 - 性能损耗:遍历深层嵌套结构可能影响性能(需结合缓存优化)。
3. 解决的问题
经典场景
- 文件系统管理
- 统一处理文件和文件夹(递归删除、大小统计)。
- UI 组件树
- GUI 中的容器(Panel)和控件(Button)统一渲染。
- 菜单系统
- 支持多级嵌套菜单(主菜单 → 子菜单 → 菜单项)。
4. 实现注意事项
关键实现点
- 接口设计
- 透明式:在
Component
接口定义add/remove
方法(叶子节点抛出异常)。 - 安全式:仅在容器接口(如
Folder
)定义add/remove
方法(推荐方式)。
- 透明式:在
- 遍历算法
- 深度优先(DFS)或广度优先(BFS)遍历树形结构。
- 空对象处理
- 叶子节点对容器操作返回默认值(如
File.getSize()
直接返回文件大小)。
- 叶子节点对容器操作返回默认值(如
代码示例(安全式实现)
java
// 抽象组件(不包含管理方法)
interface FileSystemItem {
String getName();
long getSize();
}
// 叶子节点
class File implements FileSystemItem {
private String name;
private long size;
public long getSize() { return size; }
}
// 容器节点
class Folder implements FileSystemItem {
private List<FileSystemItem> children = new ArrayList<>();
public void addItem(FileSystemItem item) { children.add(item); }
public long getSize() {
return children.stream().mapToLong(FileSystemItem::getSize).sum();
}
}
5. 实现变体
类型 | 特点 | 适用场景 |
---|---|---|
透明式组合 | 所有节点(包括叶子)实现相同的管理接口(add/remove ) | 需要极致的接口统一性 |
安全式组合 | 仅容器节点实现管理接口(更符合现实逻辑) | 大多数实际场景(推荐) |
6. 相似模式对比
模式 | 核心区别 |
---|---|
装饰器模式 | 增强单个对象功能,组合模式处理对象集合 |
享元模式 | 共享细粒度对象,组合模式管理对象结构 |
访问者模式 | 分离遍历与操作,常与组合模式配合处理复杂结构 |
7. 组合使用场景
常见搭配模式
- 迭代器模式
- 场景:为组合结构提供统一的遍历接口(如深度优先迭代器)。
- 访问者模式
- 场景:在复杂树形结构上执行多种操作(如文件系统病毒扫描+统计)。
- 责任链模式
- 场景:沿树形结构传递请求(如审批流程沿组织架构树传递)。
总结
组合模式是树形数据建模的标准方案,其核心价值在于通过一致性接口隐藏结构复杂性。安全式实现更符合现实逻辑,而透明式实现追求极致统一。在涉及递归操作的场景(如价格汇总、权限检查)中,组合模式能显著简化代码结构,但需注意避免过度泛化接口。