1.1概述
将对象组合成树形结构以表示“部分-整体”的层次结构。组合(Composite)使用户对单个对象和组合对象的使用具有一致性。这就是组合模式的定义。
如果一个对象包含另一个对象的引用,称这样的对象为组合对象。如果将当前组合对象作为一个整体的话,那么它所包含的对象就是该整体的一部分。如果一个对象不含有其他对象的引用,称这样的对象为个体对象。在编写程序时,我们希望将许多个体对象和组合对象组成树形结构,以此表示“部分-整体”的层次结构,并借助该层次结构使得用户能用一致的方式处理个体对象和组合对象。在组成的树形结构中,个体对象和组合对象都是树中的节点,但是,组合对象拥有其他节点的对象,个体对象是不具有其他子节点的叶节点。也就是说在树形结构中,组合对象所含有的对象将作为该组合对象的子节点被对待。
例如,我们常用软件上的菜单栏,分为一级菜单,二级菜单,三级菜单。其中,一级菜单中包含二级菜单,二级菜单中包含三级菜单。具体示意如下图一:
图一:菜单栏分级示例
组合模式是关于怎样将对象形成树形结构来表现整体和部分的层次结构的成熟模式。使用组合模式,可以让用户以一致的方式处理组合对象和个体对象,组合模式的关键在于无论是个体还是组合对象都实现了相同的接口或都是同一个抽象类的子类。
1.2模式的结构
组合模式包含有以下三种角色:
(1)抽象组件(Component):是一个接口(抽象类),该接口(抽象类)定义了个体对象和组合对象需要实现的关于操作其子节点的方法,比如add()、remove()以及getChild()等方法。抽象组件也可以定义个体对象和组合对象用于操作其自身的方法,比如isLeaf()。
(2)Composite节点(Composite Node):实现Component接口(或者抽象类)类的实例,Composite节点不仅实现Component接口,而且可以含有其他Composite节点或Leaf节点的引用。
(3)Leaf节点(Leaf Node):实现Component接口(或抽象类)类的实例,Leaf节点实现Component接口,不可以含有其他Composite节点或Leaf节点的引用,因此,叶节点在实现Component接口有关操作子节点的方法时,比如add()、remove()和getChild()方法,可让方法抛出一个异常,也可以实现为空操作。
组合模式结构的类图如下图二所示:
图二:组合模式的类图
1.3组合模式的优点
(1)组合模式中包含个体对象和组合对象,并形成树形结构,使用户可以方便地处理个体对象和组合对象。
(2)组合对象和个体对象实现了相同的接口,用户一般无须区分个体对象和组合对象。
(3)当增加新的Composite节点和Leaf节点时,用户的重要代码不需要做出修改。
1.4适合使用组合模式的情景
(1)当想表示对象的部分-整体层次结构。
(2)希望用户用一致的方式处理个体对象和组合对象。