简介:
组合模式描述了一组对象,它们的处理方式与相同类型对象的单个实例相同。组合的目的是将对象“组合”成树结构以表示部分-整体层次结构,实现让客户统一对待单个对象和组合。
概述:
组合设计模式可以解决什么问题?
- 应该表示部分-整体层次结构,以便客户端可以统一处理部分和整体对象
- 部分-整体层次结构应表示为树结构。
复合设计模式描述了什么解决方案?
- 为部分
Leaf
对象和整体Composite
对象定义统一的Component
接口
- 单个
Leaf
对象直接实现Component
接口,Composite
对象将请求转发给它们的子组件
这使客户端能够通过 Component
接口统一处理 Leaf
和 Composite
对象,Leaf
对象直接执行请求,Composite
对象将请求向下递归转发到它们的子组件。这使得客户端类更易于实现、更改、测试和重用。
UML 与类图:
在上面的 UML 类图中,Client 类没有直接(分别)引用 Leaf
和 Composite
类。相反,Client 引用公共 Component
接口,可以统一对待 Leaf
和 Composite
。
Leaf
类没有子类,直接实现了 Component
接口。
Composite
类维护一个子组件对象(子组件)的容器,并将请求转发给这些子组件(对于子组件中的每个子组件:child.operation())。
图中角色作用:
Component:
- 是所有组件的抽象,包括复合组件
- 声明组合中对象的接口
Leaf:
- 表示组合中的叶对象
- 实现所有组件方法
Composite:
- 表示一个复合组件(有子组件的组件)
- 实现操作children的方法
- 实现所有的 Component 方法,通常是通过将它们委托给children
例子:
下面的例子是用 Swift 编写的,它实现了一个图形类,它可以是一个椭圆,也可以是几个图形的组合。每个图形都可以打印。
/** "Component" */
protocol Graphic {
func print();
}
/** "Composite" */
struct CompositeGraphic:Graphic {
private var childGraphics:Array<Graphic>? = []
public mutating func add(graphic:Graphic){
childGraphics?.append(graphic)
}
public mutating func add(compositGraphic:CompositeGraphic){
childGraphics?.append(compositGraphic)
}
func print() {
for graphic in childGraphics! {
graphic.print()
}
}
}
/** "Leaf" */
struct Ellipse:Graphic {
func print() {
Swift.print("Ellipse")
}
}
/** Client */
struct CompositeDemo {
func main() {
//Initialize four ellipses
let ellipse1 = Ellipse()
let ellipse2 = Ellipse()
let ellipse3 = Ellipse()
let ellipse4 = Ellipse()
//Creates two composites containing the ellipses
var compositGraphic2 = CompositeGraphic()
compositGraphic2.add(graphic: ellipse1)
compositGraphic2.add(graphic: ellipse2)
compositGraphic2.add(graphic: ellipse3)
var compositGraphic3 = CompositeGraphic()
compositGraphic3.add(graphic: ellipse4)
var compositGraphic = CompositeGraphic()
compositGraphic.add(compositGraphic: compositGraphic2)
compositGraphic.add(compositGraphic: compositGraphic3)
//Prints the complete graphic (Four times the string "Ellipse").
compositGraphic.print();
}
}