设计模式之组合模式
# 引言
组合模式最大的特点就是运用的“树”这一数据结构。
在面向对象开发中,许多情况我们可以直接运用“树”的数据结构就可以解决问题。
举个例子: 在设计评论时,每篇文章可以有许多评论,每条评论可以有子评论,子评论也可以有子评论。 可以发现这就是一种树形结构。
我们看一下代码实现:
public class Comment{
private Integer id;
private Integer articleId;
private String content;
private String author;
private List<Comment> reply;
//
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
这就是“树”这一数据结构的简单运用。 当然,更特殊的“树”就是二叉树,可以定义为:
public class TreeNode{
public TreeNode left;
public TreeNode right;
}
1
2
3
4
2
3
4
# 组合模式的概念
亦称: 对象树、Object Tree、Composite
组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
简单来说就是:
组合模式是一种结构型设计模式,你可以使用它将对象组合成树状结构,并且能像使用独立对象一样使用它们。
# 问题
在实际的开发过程中,我们遇到的场景往往并不是简单的树形结构,而是具有类似于树形结构。
在这种情况向下,树结构中的每个节点,并不是同一个类型,这些显然无法直接将他们很好的组织起来。
# 组成元素:
- 抽象构件角色(Composite):是组合中对象声明接口,实现所有类共有接口的默认行为。
- 树叶构件角色(Leaf):上述提到的单个对象,叶节点没有子节点。
- 树枝构件角色(Composite):定义有子部件的组合部件行为,存储子部件,在Component接口中实现与子部件有关的操作。
- 客户端(Client):使用 Component 部件的对象。
# 优点:
- 高层模块(客户端)调用简单。组合模式使得客户端代码可以一致地处理单个对象和组合对象,无须关心自己处理的是单个对象,还是组合对象,这简化了客户端代码;
- 节点自由增加,更容易在组合体内加入新的对象,客户端不会因为加入了新的对象而更改源代码,满足“开闭原则”;
# 缺点:
- 在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则
- 设计较复杂,客户端需要花更多时间理清类之间的层次关系;
- 不容易限制容器中的构件;
- 不容易用继承的方法来增加构件的新功能;
# 组合模式的使用场景:
- 你想表示对象的部分-整体层次结构,如树形菜单,文件、文件夹的管理。文件系统由文件和目录组成,每个文件里装有内容,而每个目录的内容可以有文件和目录,目录就相当于是由单个对象或组合对象组合而成,如果你想要描述的是这样的数据结构,那么你就可以使用组合模式。
- 算术表达式包括操作数、操作符和另一个操作数,其中,另一个操作符也可以是操作数、操作符和另一个操作数。
- 在 JAVA AWT 和 SWING 中,对于 Button 和 Checkbox 是树叶,Container 是树枝。
- 你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
- 在现实生活中,存在很多“部分-整体”的关系。汽车与轮胎、发动机的关系。医院与科室、医生的关系。学校与学院、学生、老师的关系
- 如果你需要实现树状对象结构, 可以使用组合模式。
- 组合模式为你提供了两种共享公共接口的基本元素类型: 简单叶节点和复杂容器。 容器中可以包含叶节点和其他容器。 这使得你可以构建树状嵌套递归对象结构。
- 如果你希望客户端代码以相同方式处理简单和复杂元素, 可以使用该模式。
- 组合模式中定义的所有元素共用同一个接口。 在这一接口的帮助下, 客户端不必在意其所使用的对象的具体类。
# 参考文献
更新时间: 12/4/2022, 6:55:46 PM