Composite(DesignPattern)

Composite

目的

将对象组合起来,以达到能同时表达整体与局部的效果,使得用户能一致地操作单个对象和组合对象

动机

在一些系统中,用户希望通过简单的组件组合成复杂的组件,但同时由于用户认为这些组件的操作是一致的,因此不适合将组件进行区别的对待。有一种实现方法是为所有简单组件定义一些类,另外定义一些容器类来管理简单组件。但这样势必需要区别对待地操作所有组件,如果组件的组合方式很多样化,那么操作起来就很不方便。因此我们可以使用递归组合这些组件,避免用户对组件使用不同的操作。

使用范围

  • 表示对象的整体与局部的层次结构
  • 忽略组合对象与单个对象的不同,从而对其进行统一的操作

效果

  • 首先在这个设计模式中会有几个角色:component(定义公共接口),leaf(最基本的组件),composite(含有叶节点的组件);
  • composite模式使得基本对象即叶节点可以组成复合对象,同理复合对象也可以组成更大的符合对象,从而递归下去;
  • 可以简化用户代码,因为composite和leaf的接口类似,操作也相近;
  • 方便添加新组件,无论是leaf还是composite都可以自由地添加到原来的结构中,也就不会影响客户的使用;
  • 会有一些约束:
    • 因为你无法限制其添加组件,也就无法在编译时限定哪些组件可以添加进来,只能在运行时进行判断;

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// Composite.cpp : 定义控制台应用程序的入口点。
//

#include <vector>
#include <iostream>

class Component {
public:
virtual void operation(){}
virtual void add(Component* ){}
virtual void remove(Component* ){}
virtual Component* getChild(int index) { return 0; }
virtual ~Component(){}
};

class Composite :public Component{
public:
virtual void operation() {
for (auto c : com)
c->operation();
}
virtual void add(Component* c) {
com.push_back(c);
}
virtual void remove(Component* c) {

}
Component* getChild(int index) {
if (index < com.size())
return com[index];
return NULL;
}
private:
std::vector<Component* > com;
};

class Leaf :public Component {
public:
virtual void operation() {
std::cout << "leaf::operation()" << std::endl;
}
};

int main()
{
Leaf *leaf = new Leaf();
leaf->operation();
Composite *com = new Composite();
com->add(leaf);
com->operation();
Component *leaf_ = com->getChild(0);
leaf_->operation();

delete leaf;
delete com;

return 0;
}