前言

外观、装饰和组合模式(结构型设计模式)的 C++ 代码示例模板。


代码仓库


外观模式(Facade)

结构

  • 子系统类(多个)(被管理者)
  • 外观类(管理者)
  • 外观类 封装 子系统对象
  • 外观类的方案方法 调用子系统对象的方法 搭配成不同方案 (不同对象、方法(内容)和时序/步骤等)
  • 客户端只知道外观类,不知道子系统类

代码

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
#include <iostream>

using std::cout;
using std::endl;

// 子系统类(多个)(被管理者)
// 子系统 A 类
class SubsystemA
{
public:
void func_A()
{
cout << "func_A()" << endl;
}
};

// 子系统 B 类
class SubsystemB
{
public:
void func_B()
{
cout << "func_B()" << endl;
}
};

// 外观类(管理者)
class Facade
{
public:
Facade() : subsystem_A(), subsystem_B() {} // 子系统类的 默认构造方法初始化 子系统对象

// 外观类的方案方法 调用子系统对象的方法 搭配成不同方案(不同对象、方法(内容)和时序/步骤等)
// 方案1
void option1()
{
subsystem_A.func_A();
subsystem_B.func_B();
}

// 方案2
void option2()
{
subsystem_B.func_B();
subsystem_A.func_A();
}

// 方案n...

private:
// 外观类 封装 子系统对象
SubsystemA subsystem_A;
SubsystemB subsystem_B;
};

// 客户端
int main()
{
// 客户端只知道外观类,不知道子系统类
Facade facade;

facade.option1(); // 使用方案1
facade.option2(); // 使用方案2

return 0;
}
/*
输出:
func_A()
func_B()
func_B()
func_A()
*/

装饰模式(Decorator)

结构

  • 抽象组件类
  • 具体组件类(被装饰者)
  • 抽象装饰类
  • 具体装饰类(装饰者)
  • 抽象装饰类 继承 抽象组件类
  • 抽象装饰类 封装 抽象组件指针(实际上会指向一个具体组件对象)(装饰者包装被装饰者)
  • 抽象装饰类 重写 抽象组件类的方法
  • 形式上 调用 装饰类的方法
  • 实际上 调用 抽象组件指针/具体组件对象的方法(原本内容) + 装饰类的额外内容(装饰内容) (重点理解)
  • 具体装饰类 重写 抽象组件类的方法
  • 形式上 调用 装饰类的方法
  • 实际上 调用 抽象组件指针/具体组件对象的方法(原本内容) + 装饰类的额外内容(装饰内容) (重点理解)
  • 注意浅拷贝和深拷贝问题:相同组件不同装饰,需要浅拷贝
  • 注意同一组件不同装饰的重复析构问题

代码

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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <iostream>

using std::cout;
using std::endl;

// 抽象组件类
class AbstractComponent
{
public:
virtual ~AbstractComponent() = default;

virtual void func() = 0;
};

// 具体组件类(被装饰者)
class ConcreteComponent : public AbstractComponent
{
public:
void func() override
{
cout << "component" << endl;
}
};

// 抽象装饰类
// 抽象装饰类 继承 抽象组件类
class AbstractDecorator : public AbstractComponent
{
public:
// 注意浅拷贝和深拷贝问题:相同组件不同组件,需要浅拷贝
AbstractDecorator(AbstractComponent *abstract_component) : abstract_component(abstract_component) {}
virtual ~AbstractDecorator() override
{
delete this->abstract_component;
}

// 抽象装饰类 重写 抽象组件类的方法
// 形式上 调用 装饰类的方法
// 实际上 调用 抽象组件指针/具体组件对象的方法(原本内容) + 装饰类的额外内容(装饰内容)(重点理解)
void func() override
{
if (this->abstract_component != nullptr)
{
this->abstract_component->func();
}
}

private:
// 抽象装饰类 封装 抽象组件指针(实际上会指向一个具体组件对象)(装饰者包装被装饰者)
AbstractComponent *abstract_component;
};

// 具体装饰 A 类
class ConcreteDecoratorA : public AbstractDecorator
{
public:
ConcreteDecoratorA(AbstractComponent *abstract_component) : AbstractDecorator(abstract_component) {}

// 具体装饰类 重写 抽象组件类的方法
void func() override // 形式上 调用 装饰类的方法
{
AbstractDecorator::func(); // 实际上 调用 抽象组件指针/具体组件对象的方法(原本内容)
cout << "ConcreteDecoratorA" << endl; // + 装饰类的额外内容(装饰内容)(重点理解)
}
};

// 具体装饰 B 类
class ConcreteDecoratorB : public AbstractDecorator
{
public:
ConcreteDecoratorB(AbstractComponent *abstract_component) : AbstractDecorator(abstract_component) {}

// 具体装饰类 重写 抽象组件类的方法
void func() override // 形式上 调用 装饰类的方法
{
AbstractDecorator::func(); // 实际上 调用 抽象组件指针/具体组件对象的方法(原本内容)
cout << "ConcreteDecoratorB" << endl; // + 装饰类的额外内容(装饰内容)(重点理解)
}
};

// 客户端
int main()
{
// 注意同一组件不同装饰的重复析构问题
// AbstractComponent *abstract_component = new ConcreteComponent(); // 抽象组件指针/具体组件对象

// // 抽象组件指针/具体装饰 A 对象装饰组件
// AbstractComponent *concrete_decorator_A = new ConcreteDecoratorA(abstract_component);
// concrete_decorator_A->func(); // 形式上 调用 装饰类的方法

// AbstractComponent *concrete_decorator_B = new ConcreteDecoratorB(abstract_component);
// concrete_decorator_B->func();

// delete concrete_decorator_B; // 第一次 delete abstract_component
// delete concrete_decorator_A; // 第二次 delete abstract_component
// delete abstract_component; // 第三次 delete abstract_component

// 解决1:使用智能指针,shared_ptr<>
// 解决2:手动实现引用计数机制
// 解决3:程序结束自动释放全部
// 解决4:使用相同组件的不同副本
// 解决5:使用不同组件
// 解决n...
// 使用解决5
AbstractComponent *abstract_component_a = new ConcreteComponent(); // 抽象组件指针/具体组件对象
// 抽象组件指针/具体装饰 A 对象装饰组件
AbstractComponent *concrete_decorator_A = new ConcreteDecoratorA(abstract_component_a);
concrete_decorator_A->func(); // 形式上 调用 装饰类的方法
delete concrete_decorator_A; // 第一次 delete abstract_component
// delete abstract_component_a; // 第二次 delete abstract_component

AbstractComponent *abstract_component_b = new ConcreteComponent();
AbstractComponent *concrete_decorator_B = new ConcreteDecoratorB(abstract_component_b);
concrete_decorator_B->func();
delete concrete_decorator_B;

return 0;
}

组合模式(Composite)

结构

  • 组件类
  • 树叶类(树的叶节点)
  • 树枝类(树的非叶节点)
  • 树叶类 继承 组件类,重写 虚方法
  • 树枝类 继承 组件类,封装 组件类的集合(实际上包含零个或多个树叶对象或树枝对象),重写 虚方法
  • 客户端 以相同的方式处理/一致地使用 简单和复杂元素/单个和组合对象

类型

  • 透明方式:组件类有管理子对象的方法(添加组件方法和删除组件方法等),树枝类和叶子类的行为一致;但叶子类继承和实现该些方法没有意义,违反接口隔离原则(ISP)
  • 安全方式:组件类没有管理子对象的方法,树枝类有管理子对象的方法

代码(安全方式)

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
97
98
99
100
101
102
103
104
// 安全方式:组件类没有管理子对象的方法,树枝类有管理子对象的方法
#include <iostream>
#include <vector>

using std::cout;
using std::endl;
using std::vector;

// 组件类
class Component
{
public:
virtual ~Component() {}

virtual void func() = 0;
};

// 树叶类(树的叶节点)
// 树叶类 继承 组件类,重写 虚方法
class Leaf : public Component
{
public:
Leaf(int value) : value(value) {}

void func() override
{
cout << "Leaf: " << this->value << endl;

return;
}

private:
int value;
};

// 树枝类(树的非叶节点)
// 树枝类 继承 组件类,封装 组件类的集合(实际上包含零个或多个树叶对象或树枝对象),重写 虚方法
class Branch : public Component
{
public:
Branch() : component_vec() {} // vector<> 的 默认构造方法初始化 属性
~Branch()
{
for (Component *component : this->component_vec)
{
delete component;
}
}

void add(Component *component)
{
this->component_vec.push_back(component);
}

void func() override
{
cout << "Branch: " << endl;
for (Component *component : this->component_vec)
{
component->func();
}
}

private:
vector<Component *> component_vec;
};

// 客户端

int main()
{
// 树叶
Leaf *leaf_1 = new Leaf(10);
Leaf *leaf_2 = new Leaf(20);
Leaf *leaf_3 = new Leaf(30);

// 树枝
Branch *branch_1 = new Branch();
branch_1->add(leaf_1);
branch_1->add(leaf_2);

// 树枝/根
Branch *branch_2 = new Branch();
branch_2->add(leaf_3);
branch_2->add(branch_1);

// 客户端 以相同的方式处理/一致地使用 简单和复杂元素/单个和组合对象
leaf_2->func();
cout << endl;
branch_2->func();

delete branch_2; // 会自动递归 delete branch_1、leaf_2、leaf_1 和 leaf_3

return 0;
}
/*
Leaf: 20

Branch:
Leaf: 30
Branch:
Leaf: 10
Leaf: 20
*/

总结

外观、装饰和组合模式(结构型设计模式)的 C++ 代码示例模板。


参考资料


作者的话

  • 感谢参考资料的作者/博主
  • 作者:夜悊
  • 版权所有,转载请注明出处,谢谢~
  • 如果文章对你有帮助,请点个赞或加个粉丝吧,你的支持就是作者的动力~
  • 文章在描述时有疑惑的地方,请留言,定会一一耐心讨论、解答
  • 文章在认识上有错误的地方, 敬请批评指正
  • 望读者们都能有所收获