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

组合模式的定义

组合模式(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了。

相关推荐
知守观5 小时前
设计模式实战:从真实老项目中看标准模板方法与工厂的落地
java·spring·设计模式
李某学编程8 小时前
基于ARM的微机原理学习笔记(一)
arm开发·笔记·学习
sbjdhjd9 小时前
AI产业周度动态:从“更强模型”走向“可执行、可治理、可计价”的系统竞争 (2026年10月19日—10月25日)
人工智能·笔记·ai·开源·gemini·信息差·claude code
ss27310 小时前
AI时代首先数据库-PostgreSQL实战笔记 27 PostgreSQL数据写入与读取流程解析
数据库·笔记·postgresql
深圳老胡11 小时前
压力检测空吸功能硬件方案全解析:主流压力传感器品牌与实现路径
笔记·单片机·代码规范
程序猿追11 小时前
返回 null 不一定入队成功:鸿蒙 KMP上的并发优先队列观察笔记
笔记·华为·harmonyos·kmp
崔高杰12 小时前
【多论文阅读笔记】下一阶段,Agent记忆关注什么能力?
论文阅读·笔记
ms72wx12 小时前
Docker 命令学习笔记:从入门到进阶的实战指南
笔记·学习·docker
NoteDeep 深度笔记13 小时前
排期看不出冲突?把任务表切成甘特图
笔记·个人开发·甘特图·笔记应用·深度笔记·云笔记
霍霍的袁15 小时前
【C++11】左值右值引用与移动语义详细笔记(左值右值、右值引用、移动构造、移动赋值、引用折叠、万能转发)
c++·笔记·学习·visual studio