设计模式之禅——组合模式

引:部分类可以组成整体类,然后拥有一个统一的接口,这就是组合模式

定义

将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。——结构类

组合模式也叫合成模式,有时又叫做部分——整体模式,主要用来描述部分和整体的关系。下面是它的通用类图:

composite

接下来简单介绍类图的几个类:

  1. Component抽象构建角色:定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性。
  2. Leaf叶子构件:叶子对象,其下再也没有其他的分支,遍历的最小单位。
  3. Composite树枝构件:树枝对象,它的作用是组合树枝节点和叶子节点形成一个树形结构。

下面是它的通用源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// 抽象构建
public abstract class Component {
// 个体和整体都具有的共享
public void doSomething(){
// 编写逻辑业务
}
}

// 树枝构件
public class Composite extends Component {
// 构件容器
private ArrayList<Component> componentArrayList = new ArrayList<Component>();
// 增加一个叶子构件或树枝构件
public void add(Component component) {
this.componentArrayList.add(component);
}
// 删除一个叶子构件或树枝构件
public void remove(Component component) {
this.componentArrayList.remove(component);
}
// 获得分支下的所有叶子构件和树枝构件
public ArrayList<Component> getChildren() {
return this.componentArrayList;
}
}

// 树叶节点
public class Leaf extends Component {
public void doSomething() {
// 覆写父类方法
}
}

// 场景类
public class Client {
public static void main(String[] args) {
// 创建一个根节点
Composite root = new Composite();
root.doSomething();
// 创建一个树枝节点
Composite branch = new Composite();
// 创建一个叶子节点
Leaf leaf = new Leaf();
// 建立整体
root.add(branch);
branch.add(leaf);
}
// 通过递归遍历树
public static void display(Composite root) {
for(Component c : root.getChildren()) {
if (c instanceof Leaf) {
c.doSomething();
} else {
display((Composite) c);
}
}
}
}

我们可以从场景类看出组合模式破坏了依赖倒转原则,树枝和树叶直接使用了实现类。

应用

优点

  1. 高层模块调用节点,一棵树机构中的所有节点都是Component。
  2. 节点自由增加,容易扩展,符合开闭原则。

缺点

与依赖倒置原则冲突,限制了接口的影响范围。

使用场景

  1. 维护和展示部分-整体关系的场景,如树形菜单,文件和文件夹管理。
  2. 从一个整体能够独立出部分模块或功能的场景。

注意事项

只要是树形结构或者体现局部和整体的关系的时候,要考虑组合模式。

最佳实践

组合模式在项目中到处都有,比如页面结构,XML结构等等。

参考

  1. 《设计模式之禅》