前言

状态、命令和观察者模式(行为型设计模式)的 C++ 代码示例模板。


代码仓库


状态模式(State)

结构

  • 抽象状态类
  • 具体状态类
  • 上下文类
  • 抽象状态类 封装 处理方法
  • 具体状态类 重写 处理方法
  • 上下文类 封装 抽象状态指针(实际上指向一个具体状态对象)
  • 上下文类 封装 转换状态方法(删除上一个状态即当前状态, 保存下一个状态为当前状态)
  • 上下文类 封装 处理状态方法(形式上 调用 上下文类的 处理状态方法,实际上 调用 具体状态对象的处理方法)

代码

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

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

// 抽象状态类
// 抽象状态类 封装 处理方法
class AbstractState
{
public:
virtual void handle() = 0;
};

// 具体状态1类
// 具体状态类 重写 处理方法
class ConcreteState1 : public AbstractState
{
public:
void handle() override
{
cout << "ConcreteState1" << endl;
}
};

// 具体状态2类
class ConcreteState2 : public AbstractState
{
public:
void handle() override
{
cout << "ConcreteState2" << endl;
}
};

// 上下文类
// 上下文类 封装 抽象状态指针(实际上指向一个具体状态对象)
class Context
{
public:
// 转换状态方法
void convert_state(AbstractState *next_state)
{
delete this->current_state; // 删除上一个状态即当前状态
this->current_state = next_state; // 保存下一个状态为当前状态
}

// 处理状态方法
void handle_state() // 形式上 调用 上下文类的 处理状态方法
{
this->current_state->handle(); // 实际上 调用 具体状态对象的处理方法
}

private:
AbstractState *current_state = nullptr; // 当前状态,默认为空
};

// 客户端
int main()
{
// 抽象状态指针(实际上指向一个具体状态对象)
AbstractState *abstract_state_1 = new ConcreteState1();
AbstractState *abstract_state_2 = new ConcreteState2();

// 上下文对象
Context context;

context.convert_state(abstract_state_1); // 转换状态 nullptr -> abstract_state_1
context.handle_state(); // 处理状态

context.convert_state(abstract_state_2);
context.handle_state();

delete abstract_state_2;
// delete abstract_state_1; 转换状态时隐式析构

return 0;
}
/*
输出:
ConcreteState1
ConcreteState2
*/

命令模式(Command)

结构

  • 接收者类
  • 抽象命令类
  • 具体命令类
  • 发送者类
  • 接收者类 封装 行为方法
  • 抽象命令类 封装 执行方法
  • 具体命令类 重写 执行方法(形式上 调用 具体命令对象的执行方法,实际上 调用 接收者对象的行为方法)
  • 具体命令类 封装 接收者对象(如果在 抽象命令类 封装 接收者对象,接收者类型一致;如果在 具体命令类 封装 接收者对象,接收者类型可以不同)
  • 发送者类 封装 抽象命令指针(实际上指向一个具体命令对象)
  • 发送者类 封装 设置命令方法 和 执行命令方法(形式上 调用 发送者对象的执行命令方法,实际上 调用 具体命令对象的执行方法)
  • 命令执行过程:发送者 调用 执行命令方法 -> 命令 调用 执行方法 -> 接收者 调用 行为方法

代码

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

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

// 接收者类
// 接收者类 封装 行为方法
class Receiver
{
public:
void action()
{
cout << "Receiver" << endl;
}
};

// 抽象命令类
// 抽象命令类 封装 执行方法
class AbstractCommand
{
public:
virtual void execute() = 0;
};

// 具体命令类
// 具体命令类 重写 执行方法
// 具体命令类 封装 接收者对象
class ConcreteCommand : public AbstractCommand
{
public:
ConcreteCommand() : receiver() {} // 接收者类的默认构造方法 初始化 接收者对象

virtual void execute() override // 形式上 调用 具体命令对象的执行方法
{
receiver.action(); // 实际上 调用 接收者对象的行为方法
}

private:
Receiver receiver;
// 如果在 抽象命令类 封装 接收者对象,接收者类型一致
// 如果在 具体命令类 封装 接收者对象,接收者类型可以不同
};

// 发送者类
class Sender
{
public:
// 设置命令方法
void set_command(AbstractCommand *abstract_command)
{
this->abstract_command = abstract_command;
}

// 执行命令方法
void execute_command() // 形式上 调用 发送者对象的执行命令方法
{
this->abstract_command->execute(); // 实际上 调用 具体命令对象的执行方法
}

private:
// 封装 抽象命令指针(实际上指向一个具体命令对象)
AbstractCommand *abstract_command;
};

// 客户端
int main()
{
// 抽象命令指针(实际上指向一个具体命令对象)
AbstractCommand *abstract_command = new ConcreteCommand();

// 发送者对象
Sender sender;
sender.set_command(abstract_command); // 设置命令
sender.execute_command(); // 执行命令
// 命令执行过程:发送者 调用 执行命令方法 -> 命令 调用 执行方法 -> 接收者 调用 行为方法
// ender.execute_command() -> this->abstract_command->execute() -> receiver.action()

delete abstract_command;

return 0;
}
/*
输出:
Receiver
*/

观察者模式(Observer)

结构

  • 抽象观察者类
  • 具体观察者类
  • 抽象目标类
  • 具体目标类
  • 抽象观察者类 封装 更新方法
  • 具体观察者类 重写 更新方法
  • 抽象目标类 封装 抽象观察者指针(实际上指向一个具体观察者对象)的集合属性,添加观察者方法,移除观察者方法,通知观察者方法(形式上 调用 具体目标对象的 通知观察者方法,实际上 调用 具体观察者对象的 更新方法)
  • 抽象目标类 封装 状态属性,设置状态方法(设置状态后,通知观察者),获取状态方法
  • 观察过程:目标设置(改变)状态 -> 通知观察者 -> 观察者更新

代码

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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>

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

// 抽象观察者类
class AbstractObserver
{
public:
// 更新方法
virtual void update(string message) = 0;
};

// 具体观察者
class ConcreteObserver : public AbstractObserver
{
public:
ConcreteObserver(string name) : name(name) {}

// (重写)更新方法
void update(string message) override
{
cout << "Observer " << this->name << " receives message: " << message << endl;
}

private:
string name; // 名称
};

// 抽象目标类
class AbstractTarget
{
public:
virtual ~AbstractTarget()
{
for (AbstractObserver *observer : this->observer_vec)
{
delete observer;
}
this->observer_vec.clear();
}

// 添加观察者方法
void add_observer(AbstractObserver *observer)
{
this->observer_vec.push_back(observer);
}

// 移除观察者方法
void remove_observer(AbstractObserver *observer)
{
vector<AbstractObserver *>::iterator it = std::remove(this->observer_vec.begin(), this->observer_vec.end(), observer);
this->observer_vec.erase(it, this->observer_vec.end());
// 移除的观察者可能还需要,这里不 delete,由客户端构造和析构
}

// 通知观察者方法
void notify_observer(string message)
{
for (AbstractObserver *observer : this->observer_vec) // 形式上 调用 具体目标对象的 通知观察者方法
{
observer->update(message); // 实际上 调用 具体观察者对象的 更新方法
}
}

// 设置状态方法
void set_state(string state)
{
this->state = state;
this->notify_observer("State changes to: " + this->state); // 设置状态后,通知观察者
}

// 获取状态方法
// string get_state()
// {
// return this->state;
// }

private:
// 抽象观察者指针(实际上指向一个具体观察者对象)的集合属性
vector<AbstractObserver *> observer_vec;
string state; // 状态属性
};

// 具体目标类
class ConcreteTarget : public AbstractTarget
{
// 简单实现,不需要额外内容
};

// 客户端
int main()
{
// 具体目标类
ConcreteTarget concrete_target;

// 具体观察者对象
AbstractObserver *concrete_observer_1 = new ConcreteObserver("concrete_observer_1");
AbstractObserver *concrete_observer_2 = new ConcreteObserver("concrete_observer_2");

// 添加观察者
concrete_target.add_observer(concrete_observer_1); // 具体观察者对象1 观察 具体目标
concrete_target.add_observer(concrete_observer_2); // 具体观察者对象2 观察 具体目标

// 设置状态
concrete_target.set_state("state1");
// 观察过程:
// 目标设置(改变)状态 -> 通知观察者 -> 观察者更新
// concrete_target.set_state() -> this->notify_observer() -> observer->update()

// 移除观察者
concrete_target.remove_observer(concrete_observer_1);
delete concrete_observer_1;

// 设置状态
concrete_target.set_state("state2");

// 局部变量 concrete_target 销毁,隐式析构 delete concrete_observer_2

return 0;
}
/*
输出:
Observer concrete_observer_1 receives message: State changes to: state1
Observer concrete_observer_2 receives message: State changes to: state1
Observer concrete_observer_2 receives message: State changes to: state2
*/

总结

状态、命令模式和观察者模式(行为型设计模式)的 C++ 代码示例模板。


参考资料


作者的话

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