http://www.oodesign.com/composite-pattern.html
首先明确该模式要解决的问题是当我们面对一个树形结构时,比如文件系统。文件夹里包含其他的文件夹和文件。如何对外提供一个统一的接口:客户端不关心操作对象是一个folder还是一个file,它面向接口操作。
我看有文章把composite翻译成树形模式。
因此该模式包含以下要素:
component: 对外提供一个接口。也就是说component是leaf和composite可提供的服务的抽象。在文件系统的例子中,是可以对文件和文件夹操作的抽象。
Component is the abstraction for leafs and composites. It defines the interface that must be implemented by the objects in the composition. For example a file system resource defines move, copy, rename, and getSize methods for files and folders.
composite: 在文件系统中,可以代表一个文件夹:它会有child,同时child是包含了文件夹和文件的混合体。
leaf: 在文件系统中,代表一个文件:没有child,是leaf level的对象。
上图的特殊之处就在于,一个包含了文件和文件夹的混合体composite,可以操作的对象是实现了component接口的对象。也就是说一个混合体可以任意的添加、删除文件或文件夹或composite。因为composite可以轻易实现复杂的复合对象。
举一个更复杂一点的例子:
一个绘图软件,绘制的图形由一些基本element构成:直线,圆,椭圆,箭头等等。在该模式中,这些对象就是leaf,特点是不能再包含子对象。而一副图片,则由这些基本的element构成,更进一步,一幅大图可以由多个小图+leaf对象构成。因此在一个composite中可以任意的添加、删除子图或leaf对象。对于client(绘图软件)来说,操作的是一个统一的接口(不管是复杂图形还是仅仅是一条直线)。
讲到这里可以引入另一个设计模式 Decorator
感觉上这两种模式很像,我的理解是Decorator中包含的对象之间没有明显的父子关系。也就是说composite代表的不是一个树形结构。
比如一个咖啡店中卖出的一杯咖啡是一个基本对象;一杯咖啡+2块方糖;一杯咖啡+2块方糖+牛奶;又代表了复合对象。
如何灵活的处理所有可能的组合就是Decorator要解决的问题。
由于Decorator处理的不是树形结构,因此它和composite的区别就在于leaf和composite不能抽象出同样的接口。就如同咖啡店可以买咖啡,加了糖的咖啡,但是不可以单卖方糖一样。
不过这两种模式真的很像。