组合模式 Composite
We want to make the client using the Container or Leafs in a same calling way, so we set the leaf and the container that implement the same interface (Component). And the Container contains some children. In this way we create a model like tree, the client can treat every node similarly.
为了使客户端能够使用相同的方式调用 “容器” 和 “叶子”,我们让容器和叶子都去实现同一个接口 “组件”。并且容器中包含有一些子的容器。通过这种方式,我们可以创建一个类似于一棵树的模型,客户端对每个结点使用相同的对待方式。
// interface
protocol Component {
func execute()
}
class Leaf: Component {
func execute() {
print("I'm leaf")
}
}
class SubLeaf: Leaf {
override func execute() {
print("I'm sub leaf")
}
}
// Composite
class Containner:Component {
private var children: [Component] = []
func add(c: Component) {
children.append(c)
}
func remove(c: Component) {
}
func execute() {
for item in children {
item.execute()
}
}
}
// We treat the leaf and the containner as the same type of node.
let leaf = Leaf()
let leafTwo = Leaf()
let subLeaf = SubLeaf()
let c = Containner()
c.add(c: leaf)
c.add(c: leafTwo)
let root = Containner()
root.add(c: c)
root.add(c: subLeaf)
c.execute()
root.execute()
如上图:
- root 持有 c 的引用,c 持有 leaf 和 leafTwo 的引用。root 和 c 是 Container 类型,leafTwo 是 Leaf 类型。
- 容器和叶子都遵守了 “组件” 协议,所以都应当有 execute 方法,只是实现方式不同(容器是访问所有子结点,叶子是只访问当前)。并且,容器和叶子可以在需要的时候,都视作 “组件” 来使用。