组合模式

组合模式能够把对象组织成树形结构,然后用统一的接口处理它们,非常优雅。

比如文件系统,目录和文件就组成了一个树形结构,树的根节点就是根目录,其中包含若干目录和文件。任意一个目录中可以包含若干目录或文件,无限嵌套下去。

再比如图形编辑器,我们可以创建基本图形,又可以把若干基本图形合并成一组,方便进行统一的移动、缩放操作。成组的图形也可以视为一个基本图形,继续和其他图形合并成一组,这样无限合并下去。

在这些场景中,我们既需要处理「独立」对象(例如文件、基本图形),又需要处理「组合」对象(例如文件夹、形状组),而且我们希望对「组合」对象和「独立」对象进行统一处理(例如查看、移动、缩放等)。

组合模式(Composite Pattern) 的核心思想就是:像对待独立对象一样,统一地处理对象组合。它允许我们将对象组合成树状结构,让组合对象和独立对象提供统一的接口,从而简化客户端代码。

如果你学过算法中的树结构,会发现组合模式的底层就是树的应用。实际上 惰性展开多叉树 那道算法题的场景就是典型的组合模式,感兴趣可以对照看看。

言归正传,组合模式主要包含以下几个核心角色:

  • 组件接口(Component):为组合中的所有对象(包括叶子节点和组合节点)定义一个统一的接口。
  • 叶子节点(Leaf):表示组合中的叶子节点对象,它没有子节点。
  • 组合节点(Composite):表示组合中的容器节点,它可以包含若干子节点,子节点类型可以是叶子节点也可以是组合节点。组合节点可以调用子节点的接口方法,然后聚合结果。

举两个例子就能直观地理解组合模式了。