1. 组合模式:树形结构的艺术
在软件开发中,我们经常遇到需要处理树形结构数据的场景。想象一下文件系统中的文件夹和文件关系,或者企业组织架构中的部门和员工关系。这些场景都有一个共同特点:它们都是由部分组成的整体,并且整体和部分可以被统一对待。这正是组合模式(Composite Pattern)大显身手的地方。
组合模式是一种结构型设计模式,它允许你将对象组合成树形结构来表示"部分-整体"的层次关系。通过这个模式,客户端可以一致地处理单个对象和组合对象,无需关心自己处理的是单个元素还是整个组合结构。
组合模式的核心思想是:用一致的方式处理树形结构中的每个节点,无论它是叶子节点还是分支节点。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 组合模式的结构解析
2.1 模式角色与职责
组合模式包含三个核心角色:
-
Component(抽象组件):定义所有组件的通用接口,包括管理子组件的方法(如add、remove)和操作子组件的方法(如operation)。它为所有具体组件声明接口,在适当情况下实现所有类共有接口的默认行为。
-
Leaf(叶子组件):表示组合中的叶子节点对象。叶子节点没有子节点,实现了Component接口中定义的操作行为。
-
Composite(组合组件):定义有子部件的部件行为,存储子部件,并在Component接口中实现与子部件有关的操作。
2.2 UML类图解析
plaintext复制┌─────────────────────────┐
│ Component │
├─────────────────────────┤
│ + operation() │
│ + add(Component) │
│ + remove(Component) │
│ + getChild(int) │
└─────────────────────────┘
△
│
┌──────┴───────┐
│ │
┌─────────┐ ┌──────────┐
│ Leaf │ │ Composite│
├─────────┤ ├──────────┤
│ │ │- children│
│ │ │ │
└─────────┘ └──────────┘
这个类图清晰地展示了组合模式的结构:
- Component定义了所有组件的通用接口
- Leaf实现了Component接口,但没有子组件
- Composite实现了Component接口,并且包含子组件集合
3. 组合模式的实现方式
3.1 透明组合模式
透明组合模式将组合和叶子节点的方法都放在Component抽象类中,这样客户端可以一致地对待所有对象。这是最常用的实现方式。
java复制public abstract class Component {
public abstract void operation();
public void add(Component component) {
throw new UnsupportedOperationException();
}
public void remove(Component component) {
throw new UnsupportedOperationException();
}
public Component getChild(int index) {
throw new UnsupportedOperationException();
}
}
优点:
- 客户端可以一致地对待所有对象
- 新增组件类型更容易,客户端无需改变
缺点:
- 不够安全,叶子节点也需要实现与子组件相关的方法(虽然只是抛出异常)
3.2 安全组合模式
安全组合模式将管理子组件的方法移到Composite类中,这样Leaf类就不需要实现这些方法。
java复制public abstract class Component {
public abstract void operation();
}
public class Composite extends Component {
private List<Component> children = new ArrayList<>();
@Override
public void operation() {
for (Component child : children) {
child.operation();
}
}
public void add(Component component) {
children.add(component);
}
public void remove(Component component) {
children.remove(component);
}
public Component getChild(int index) {
return children.get(index);
}
}
优点:
- 更安全,Leaf类不需要实现与子组件无关的方法
缺点:
- 不够透明,客户端需要知道组件的具体类型
- 新增组件类型更困难,可能需要修改客户端代码
4. 组合模式的实际应用:网关拓扑系统
4.1 场景分析
在网络设备管理系统中,设备通常以树形结构组织:
- 主网关可以包含从网关和STA设备
- 从网关可以包含其他从网关和STA设备
- STA设备是终端设备,不能再包含其他设备
这种结构非常适合使用组合模式来实现,因为:
- 存在明显的"部分-整体"层次关系
- 需要对整个结构执行统一操作(如统计设备数量、查找设备等)
- 客户端希望以一致的方式处理单个设备和设备组
4.2 核心实现
4.2.1 抽象组件:NetworkDevice
java复制public abstract class NetworkDevice {
protected String deviceId;
protected String name;
protected String type;
protected String ip;
protected String mac;
protected boolean online
