组合模式:树形结构
摘要生成中...
AI 摘要
Hunyuan-lite

组合模式 Composite Design Pattern
Compose objects into tree structure to represent part-whole hierarchies.Composite lets client treat individual objects and compositions of objects uniformly.——GoF
将一组对象组织成树形结构,以表示一种「部分 - 整体」的层次结构。组合让客户端可以统一单个对象和组合对象的处理逻辑。
使用组合模式使容器与内容具有一致性,又称为多个和单个的一致性,将多个对象结合在一起,当作一个对象进行处理,创造出递归结构。
Composite:混合物、复合物


登场角色:
Leaf(树叶):表示「内容」的角色。在该角色中不能放入其他对象。Composite(复合物):表示容器的角色。可以在其中放入Leaf角色和Composite角色。Component:使Leaf角色和Composite角色具有一致性的角色。Composite角色是Leaf角色和Composite角色的父类。Client:使用组合模式的角色。
组合模式以递归方式处理对象树中的所有项目。该方式的最大优点在于无需了解构成树状结构的对象的具体类。也无需了解对象是简单的产品还是复杂的盒子。只需调用通用接口以相同的方式对其进行处理即可。当调用该方法后,对象会将请求沿着树结构传递下去。

应用场景:
- 实现树状对象结构
- 客户端代码以相同方式处理简单和复杂元素
| 优点 | 缺点 |
|---|---|
| 利用多态和递归机制更方便地使用复杂树结构。 | 对于功能差异较大的类,提供公共接口或许会有困难。 在特定情况下,需要过度一般化组件接口,使其变得令人难以理解。 |
| 开闭原则。无需更改现有代码,就可以在应用中添加新元素,使其成为对象树的一部分。 |
相关的设计模式:
- 站内文章装饰器模式:组合模式的 UML 和装饰器模式很像,具体详看装饰器模式的介绍文章。
- [[「用类来表现」的设计模式|命令模式]]:使用命令模式编写宏命令时使用了组合模式。
- 站内文章迭代器模式:用迭代器遍历组合树。
- 站内文章访问者模式:可以使用访问者模式访问组合模式中的递归结构。
- 站内文章建造者模式:在创建复杂组合树时使用生成器模式,因为这可使其构造步骤以递归的方式运行。
- 站内文章责任链模式:叶组件接收到请求后,可以将请求沿包含全体父组件的链一直传递至对象树的底部。
- [[享元模式:共享实例|享元模式]]:实现组合树的共享叶结点以节省内存。
组合模式的应用
与其说组合模式是一种设计模式,倒不如说是对业务场景的一种数据结构和算法的抽象。其中,数据可以表示成树这种数据结构,业务需求可以通过在树上的递归遍历算法来实现。
在程序世界中,到处都存在递归结构。比如视窗系统中,一个窗口可以含有一个子窗口;文章列表中,各列表之间可以相互嵌套;计算机命令的宏命令的实现。通常来说,树结构的数据结构都适用于组合模式。
一个文件系统的例子


对于 Composite 中有一些有别于 Leaf 的方法,比如上面文件系统中的 add 方法,这些方法应当如何处理?
- 方法 1:定义在
Entry类中,默认报错。- 将
add方法定义在Entry类中,让其报错,这是上图 UML 中的示例做法。能使用add方法的只有Directory类,它会重写add方法,根据需求实现其处理。File类会继承Entry类的add方法,虽然也可以调用它的add方法,不过会抛出异常。
- 将
- 方法 2:定义在
Entry类中,但什么都不做。 - 方法 3:声明在
Entry类中,但不实现。- 在
Entry类中声明add抽象方法。如果子类需要add方法就根据需求实现该方法,如果不需要add方法,则可以简单地报错。该方法的优点是所有子类必须都实现add方法,不需要add方法时的处理也可以交给子类自己去做决定。不过,使用这种实现方法时,在File一方中也必须定义本来完全不需要的add(有时还包括remove和getchild)方法。
- 在
- 方法 4:只定义在
Directory类中。- 因为只有
Directory类可以使用add方法,所以可以不在Entry类中定义add方法,而是只将其定义在Directory类中。不过,使用这种方法时,如果要向Entry类型的变量(实际保存的是Directory类的实例)中add时,需要先将它们一个一个地类型转换(cast)为Directory类型。
- 因为只有
本文参考
- 《图解设计模式》第 11 章
- 本科生课程笔记《程序设计中级实践&设计模式》 - TJU 🍐⚱️
- 极客时间专栏 - 设计模式之美 - 王争
- 组合设计模式
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 半方池水半方田!
评论





