Java GUI组件使用了组合设计模式。考虑Swing组件类JPanel,它扩展了类JComponent。类JComponent扩展了类java.awt.Container,而java.awt.Container 又扩展了类java.awt.Component。类Container提供方法add,该方法将一个Component对象(或Component子类对象)添加到该Container对象上。因此,JPanel对象可以被添加到任意一个Component子类对象(Container对象或其子类对象),任何一个Component子类对象也可以被添加到JPanel对象上。JPanel对象可以包含任何一种GUI组件。而它不必了解组件的具体类型。一个客户(诸如一个JPanel对象)可以统一地遍历层次结构中的所有组件。比如说,如果这个JPanel对象调用超类Container的方法repaint,方法repaint将显示此JPanel对象以及添加到该JPanel对象上的所有组件。方法repaint不必判断每一个组件的类型,因为所有组件都继承超类Container,此超类包含方法repaint。
设计者经常将组件组织成层次结构(例如,硬盘上的目录和文件层次结构)---结构中的每一个节点代表一个组件(比如一个文件或目录)。每一个节点可以包含其它文件的引用。如果一个节点包含对一个或多个节点的引用(比如一个文件),那么我们把它叫做分支。如果一个节点不包含对其它节点的引用(比如一个文件),那么我们把它叫做叶子。有时候一个结构包含来自若干不同类的对象(比如一个目录可以包含文件和目录),当对象(叫做客户)想要遍历此结构的时候,该客户必须判断出每一个节点的具体类。做这种判断是耗时的,结构也变得难以维护。
在组合设计模式中,位于层次结构中的每一个组件实现相同的接口,或扩展共同的超类。这种多态性确保客户可以统一的遍历结构中的所有元素(分支或叶子都可以)。通过这个模式,对结构进行遍历的客户不必判断每一个组件的类型,因为所有的组件实现相同的接口或扩展同一个超类。
意图:
将对象组织成树形结构来表示部分--整体层次结构。Composite设计模式使得客户统一地对待处理单个对象和组合对象。
动机:
Composite模式描述了如何使用递归组合,使得用户不对叶子和分支进行区分,即统一处理他们。
Composite模式的关键是一个既能代表分支又能代表叶子的抽象类。
实现:
抽象类需要提供管理分支的一些函数。继承的时候,如果是叶子节点类则不重写这些管理分支的函数,如果是分支节点类则需要继承这些管理函数。分支节点类和叶子节点类都继承这个抽象类。分支节点类则由抽象类聚合而成(分支节点类含有数个抽象类的子类的对象引用)。