《设计模式之禅》笔记摘录 - 14.组合模式

发布于:2025-08-09 ⋅ 阅读:(20) ⋅ 点赞:(0)

组合模式的定义

组合模式(Composite Pattern)也叫合成模式,有时又叫做部分一整体模式(Part-Whole),主票是用来描述部分与整体的关系,其定义如下:

Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. (将对象组合成树形结构以表示部分—整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。)

Component,抽象构件。角色定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性。

Leaf,叶子构件。叶子对象,其下再也没有其他的分支,也就是遍历的最小单位。

Composite,树枝构件。树枝对象,它的作用是组合树枝节占和叶子节点形成一个树形结构。

组合模式的应用

组合模式的优点

高层模块调用简单。一棵树形机构中的所有节点都是Component,局部和整体对调用者来说没有任何区别,也说,高层模块不必关心自己处理的是单个对象还是整个组合结构,简化了高层模块的代码。

节点自由增加。使用了组合模式后,我们可以看看,如果想增加一个树枝节点、树叶节点是不是都很容易,只要找到它的父节点就成,非常容易扩展,符合开闭原则,对以后的维护非常有利。

组合模式的缺点

组合模式有一个非常明显的缺点,看到我们在场景类中的定义,提到树叶和树枝使用时的定义了吗?直接使用了实现类!这在面向接口编程上是很不恰当的,与依赖倒置原则冲突,读者在使用的时候要考虑清楚,它限制了你接口的影响范围。

组合模式的使用场景

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

组合模式的注意事项

只要是树形结构,要考虑使用组合模式,这个一定要记住。

只要是要体现局部和整体的关系的时候,而且这种关系还可能比较深,考虑一下组合模式吧。

组合模式的扩展

透明的组合模式

透明模式是把用来组合使用的方法放到抽象类中,比如add()、remove()以及getChildren()等方法(顺便说一下,getChildren一般返回的结果为Iterable的实现类,很多,大家可以看JDK的帮助),不管叶子对象还是树枝对象都有相同的结构,通过判断是getChildren的返回值确认是叶子节点还是树枝节点,如果处理不当,这个会在运行期出现问题,不是很建议的方式;

安全的组合模式

安全模式就不同了,它是把树枝节点和对叶节点彻底分开,树枝节点单独拥有用来组合的方法,这种方法比较安全。

组合模式的遍历

如果要从下往上遍历,怎么处理呢?甭管是树枝节点还是树叶节点,在每个节点都增加了一个属性:父节点对象,这样在树枝节点增加子节点或叶子节点时设置父节点,然后你看整棵树除了根节点外每个节点都有一个父节点,之后逐层向上查找即可。

最佳实践

组合模式在项目中到处都有,比如现在的页面结构一般都是上下结构,上面放系统的Logo,分为两部分:左边是导航菜单,右边是展示区,左边的导航菜单一般都是树形的结构,比父清晰,有非常多的JavaScript源码实现了类似的树形菜单,大家可以到网上搜索一下。还有,大家常用的XML结构也是一个树形结构,根节点、元素节点、值元素这些都与我们的组合模式相匹配,之所以本章节不以XML为例子讲解,是因为很少有人还直接读写XML文件,一股都是用JDOM或者DOM4J了。


网站公告

今日签到

点亮在社区的每一天
去签到