在工作和日常生活中,我们会接触到很多可以将对象组合成树形结构来表示“部分-整体”这种层次结构的事物,比如电脑中文件目录的组织,公司中的组织架构等。
组合模式(Composite Design Pattern)就是专门处理这种可以用“部分-整体”层次结构来表示的数据对象的。
正是由于这种应用场景的特殊性,所以组合模式的应用不是特别多,但是当符合这种场景时,组合模式就能发挥巨大的作用。
优缺点
优点
- 统一整体和单一个体的结构,调用更加统一。
- 方便自由增减子节点。
缺点
- 应用场景有限,局限性大。
- 结构之间的关联都是实体,违反了基于抽象接口编程的原则。
组合模式的构成
抽象类:定义了整体和个体共同需要实现的方法和属性,规范了整体和个体的共同点。
单一个体类:特点为没有子节点。
整体类:有容器特征,可以包含子节点。
通过一个文件目录组织的例子来实现组合模式。组合模式将一组对象组织(Compose)成树形结构,以表示一种“部分 - 个体”的层次结构。
文件目录树就是这种模式的典型应用。一个目录下,既有子目录,又有文件,目录和文件都是文件系统中统一的表示。
抽象类
class Node:
def __init__(self, path):
self.path = path
定义了抽象的文件节点类,每个文件节点,都有自己的路径名。
单一个体类
class FileNode(Node):
def __init__(self, path):
super().__init__(path)
self.is_file = True
文件系统中,每个文件都是一个单一个体类,文件不能再包含子节点。
整体类
class DirNode(Node):
def __init__(self, path):
super().__init__(path)
self.is_file = False
self.sub_node = []
def add_node(self, node: Node):
"""添加子节点"""
self.sub_node.append(node)
def delete_node(self, node: Node):
"""删除子节点"""
self.sub_node.remove(node)
文件系统中,目录就是一个整体类,它是一个容器,下面可以再包含目录或者文件这样的嵌套树形结构。
总结
组合模式的设计思路,与其说是一种设计模式,倒不如说是对业务场景的一种数据结构和算法的抽象。其中,数据可以表示成树这种数据结构,业务需求可以通过在树上的递归遍历算法来实现。
使用组合模式的前提在于,你的业务场景必须能够表示成树形结构。所以,组合模式的应用场景也比较局限,它并不是一种很常用的设计模式,但是对于适用的场景,能发挥非常大的作用。