设计模式探秘-18-组合模式

组合模式的学习与实践

组合模式

组合模式:将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。

类图

  1. Component 抽象构件角色 定义参加组合对象的公有方法和属性,可以定义一些默认的行为和属性
  2. Leaf 叶子构件 叶子对象,其下不再有分支,遍历的最小单位
  3. Composite 树枝构建 组合树枝节点和叶子节点形成树形结构

优点

  1. 高层模块调用简单
  2. 节点自由添加

缺点

直接使用实现类,在面向接口编程上很不恰当,与依赖倒置原则冲突。

使用场景

  1. 维护和展示部分——整体关系的场景
  2. 从一个整体中能够独立出部分模块或功能的场景

注意事项

只要是树形结构就可以考虑组合模式,只要是要体现局部和整体的关系,而关系比较深,考虑组合模式。

扩展

  1. 组合模式实现 透明模式 具体操作在抽象类中定义实现
  2. 组合模式实现 安全模式 具体操作在具体类中定义实现

实践

简单实现

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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Component
{
public:
Component()
{
}
virtual ~Component()
{
}
public:
virtual void Operation() = 0;
virtual void Add(const Component *com)
{
}
virtual void Remove(const Component *com)
{
}
virtual Component* GetChild(int)
{
return nullptr;
}
};

class Componsite : public Component //中间节点,可添加子节点
{
public:
Componsite()
{
}
~Componsite()
{
}
public:
void Operation()
{
for(auto it : m_vCom)
{
it->Operation();
}
}
void Add(Component *com)
{
m_vCom.push_back(com);
}
void Remove(Component *com)
{
auto it = find(m_vCom.begin(), m_vCom.end(), com);
if(it != m_vCom.end())
{
m_vCom.erase(it);
}
}
Component* GetChild(int index)
{
if(index >= m_vCom.size())
{
return nullptr;
}
return m_vCom[index];
}
private:
vector<Component*> m_vCom;
};

class Leaf : public Component //叶子节点,不可添加子节点
{
public:
Leaf()
{
}
~Leaf()
{
}
void Operation()
{
cout<<"Leaf "<<__FUNCTION__<<endl;
}
};

int main()
{
Leaf *l = new Leaf();
l->Operation();
Componsite *com = new Componsite();
com->Add(l);
com->Operation();
Component *ll = com->GetChild(0);
ll->Operation();
return 0;
}

参考资料

  1. 设计模式之禅
  2. GoF+23种设计模式解析