命令模式(Command Pattern)
# 命令模式(Command Pattern)
# 概念
命令模式是一种行为设计模式,它将请求封装成一个对象,从而允许使用不同的请求、队列或日志请求参数化客户端,并支持可撤销的操作。
# 思想
命令模式的思想是将请求封装成对象,使得请求的发起者和执行者解耦。请求者只需要创建一个命令对象并将其发送给执行者,而无需知道具体执行的操作或执行者的细节。
# 角色
- Command(命令):声明执行操作的接口。
- ConcreteCommand(具体命令):实现 Command 接口,将一个接收者对象绑定于一个动作。
- Receiver(接收者):执行具体命令时的相关操作。
- Invoker(调用者):要求命令执行请求的对象。
- Client(客户端):创建一个具体命令对象并设置它的接收者。
# 优点
- 解耦请求的发送者和接收者。
- 可以轻松地设计一个命令队列。
- 支持可撤销的操作。
- 支持操作的记录与恢复。
# 缺点
- 会导致命令类的数量增加。
# 类图
@startuml
class Client {
+main()
}
interface Command {
+execute()
}
class ConcreteCommand1 {
-receiver: Receiver
+execute()
}
class ConcreteCommand2 {
-receiver: Receiver
+execute()
}
class Receiver {
+action()
}
class Invoker {
-command: Command
+setCommand(command: Command)
+executeCommand()
}
Client --> Invoker
Invoker o--> Command
Command <|.. ConcreteCommand1
Command <|.. ConcreteCommand2
ConcreteCommand1 --> Receiver
ConcreteCommand2 --> Receiver
note top of Command: 命令接口,\n声明执行操作的方法
note top of ConcreteCommand1: 具体命令类,\n绑定一个接收者和一个动作
note top of ConcreteCommand2: 具体命令类,\n绑定一个接收者和一个动作
note top of Receiver: 接收者,\n执行具体命令时的相关操作
note top of Invoker: 调用者,\n要求命令执行请求的对象
@enduml
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
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
# 时序图
@startuml
participant Client
participant Invoker
participant ConcreteCommand1
participant Receiver
Client -> Invoker: setCommand(ConcreteCommand1)
Client -> Invoker: executeCommand()
Invoker -> ConcreteCommand1: execute()
ConcreteCommand1 -> Receiver: action()
@enduml
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 示例代码
下面是一个简单的示例代码,使用C++实现命令模式。该示例模拟了一个遥控器,遥控器上有两个按钮,分别控制电视的打开和关闭操作。
#include <iostream>
// Command Interface
class Command {
public:
virtual void execute() = 0;
};
// Concrete Command for turning on the TV
class TurnOnCommand : public Command {
private:
TV& tv;
public:
TurnOnCommand(TV& tv) : tv(tv) {}
void execute() override {
tv.turnOn();
}
};
// Concrete Command for turning off the TV
class TurnOffCommand : public Command {
private:
TV& tv;
public:
TurnOffCommand(TV& tv) : tv(tv) {}
void execute() override {
tv.turnOff();
}
};
// Receiver
class TV {
public:
void turnOn() {
std::cout << "TV is turned on." << std::endl;
}
void turnOff() {
std::cout << "TV is turned off." << std::endl;
}
};
// Invoker
class RemoteControl {
private:
Command* onCommand;
Command* offCommand;
public:
void setOnCommand(Command* command) {
onCommand = command;
}
void setOffCommand(Command* command) {
offCommand = command;
}
void pressOnButton() {
onCommand->execute();
}
void pressOffButton() {
offCommand->execute();
}
};
int main() {
TV tv;
TurnOnCommand turnOnCommand(tv);
TurnOffCommand turnOffCommand(tv);
RemoteControl remoteControl;
remoteControl.setOnCommand(&turnOnCommand);
remoteControl.setOffCommand(&turnOffCommand);
remoteControl.pressOnButton(); // 打开电视
remoteControl.pressOffButton(); // 关闭电视
return 0;
}
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
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
# 示例代码描述
上述示例代码实现了一个遥控器控制电视的功能。命令接口(Command)定义了执行操作的方法(execute),具体命令类(TurnOnCommand和TurnOffCommand)分别绑定了接收者(TV)的打开和关闭操作。遥控器(RemoteControl)充当调用者,它可以设置具体命令,并通过调用执行命令的方法来实现对电视的操作。运行示例代码会输出电视打开和关闭的信息。
运行示例代码的输出结果如下:
TV is turned on.
TV is turned off.
1
2
2
编辑 (opens new window)
上次更新: 2023/06/09, 13:17:31
- 01
- Linux系统移植(五)--- 制作、烧录镜像并启动Linux02-05
- 03
- Linux系统移植(三)--- Linux kernel移植02-05