命令模式

scorlw 发布于

命令模式

设计模式

Command模式也叫命令模式,是行为设计模式的一种。Command模式通过被称为Command的类封装了对目标对象的调用行为以及调用参数。

在面向对象的程序设计中,一个对象调用另一个对象,一般情况下的调用过程是:创建目标对象实例;设置词用参数;词用目标对象的方法。

但在有些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种专门的类称作 command类。

整个调用过程比较繁杂,或者存在多处这种调用。这时,使用 Command类对该调用加以封装,便于功能的再利用。

调用前后需要对调用参数进行某些处理。调用前后需要进行某些额外处理,比如日志,缓存,记录历史操作等。

image-20201020230528330

Command

​ Command命令的抽象类

ConcreteCommand

​ Command命令的具体实现类

Receive

​ 需要被调用的目标对象

Invorker

​ 通过Invorker执行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
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include <iostream>
#include <list>

using namespace std;

class Doctor
{
public:
void treat_eye()
{
cout << "医生 治疗 眼科病" << endl;
}

void treat_nose()
{
cout << "医生 治疗 鼻科病" << endl;
}

void treat_mouth()
{
cout << "医生 治疗 口腔科病" << endl;
}
protected:
private:
};

class Command
{
public:
virtual void treat() = 0;
protected:
private:
};

class CommandTreatEye : public Command
{
public:
CommandTreatEye(Doctor* doctor)
{
m_doctor = doctor;
}
void treat()
{
m_doctor->treat_eye();
}
protected:
private:
Doctor* m_doctor;
};

class CommandTreatNose : public Command
{
public:
CommandTreatNose(Doctor* doctor)
{
m_doctor = doctor;
}
void treat()
{
m_doctor->treat_nose();
}
protected:
private:
Doctor* m_doctor;
};

class Nurse
{
public:
Nurse(Command* command)
{
m_command = command;
}
void SubmittedCase()//提交病例(提交命令)
{
m_command->treat();
}
protected:
private:
Command* m_command;
};

//护士长
class HeadNurse
{
public:
HeadNurse()
{
m_list.clear();
}
void setCommand(Command* command)
{
m_list.push_back(command);
}
void SubmittedCase()//提交病例(提交命令)
{
for(auto command : m_list)
{
command->treat();
}
}
protected:
private:
list<Command*> m_list;
};

int main()
{
//1.医生直接看病
/*
Doctor* doctor = new Doctor;
doctor->treat_eye();
delete doctor;
*/

//2.通过命令医生来看病
/*
Doctor* doctor = new Doctor;
CommandTreatEye* commandtreateye = new CommandTreatEye(doctor);
commandtreateye->treat();
delete commandtreateye;
delete doctor;
*/

//3.通过护士提交病例实现医生看病
/*
Doctor* doctor = new Doctor;
Command* command0 = new CommandTreatEye(doctor);
//Command* command1 = new CommandTreatNose(doctor);//可以面向命令编程,实现客户端与命令的解耦合
Nurse* nurse = new Nurse(command0);
//Nurse* nurse = new Nurse(command1);
nurse->SubmittedCase();
delete nurse;
delete command0;
//delete command1;
delete doctor;
*/

//4.通过护士长批量下达命令
Doctor* doctor = new Doctor;
Command* command0 = new CommandTreatEye(doctor);
Command* command1 = new CommandTreatNose(doctor);
HeadNurse* headNurse = new HeadNurse;
headNurse->setCommand(command0);
headNurse->setCommand(command1);
headNurse->SubmittedCase();
delete headNurse;
delete command0;
delete command1;
delete doctor;

cout << "Hello world!" << endl;
return 0;
}

输出:

1
2
3
医生 治疗 眼科病
医生 治疗 鼻科病
Hello world!