我将为您创建一个命令模式的完整示例。命令模式是一种行为设计模式,它将请求封装成对象,从而使您可以用不同的请求对客户进行参数化。

命令模式示例代码

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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#include <iostream>
#include <vector>
#include <memory>

// 命令接口
class Command {
public:
virtual ~Command() = default;
virtual void execute() = 0;
virtual void undo() = 0;
};

// 接收者类 - 灯
class Light {
private:
std::string location;
bool isOn;

public:
explicit Light(const std::string& location) : location(location), isOn(false) {}

void turnOn() {
isOn = true;
std::cout << location << " 灯已打开\n";
}

void turnOff() {
isOn = false;
std::cout << location << " 灯已关闭\n";
}

bool getState() const {
return isOn;
}
};

// 具体命令类 - 打开灯
class LightOnCommand : public Command {
private:
std::shared_ptr<Light> light;

public:
explicit LightOnCommand(std::shared_ptr<Light> light) : light(light) {}

void execute() override {
light->turnOn();
}

void undo() override {
light->turnOff();
}
};

// 具体命令类 - 关闭灯
class LightOffCommand : public Command {
private:
std::shared_ptr<Light> light;

public:
explicit LightOffCommand(std::shared_ptr<Light> light) : light(light) {}

void execute() override {
light->turnOff();
}

void undo() override {
light->turnOn();
}
};

// 接收者类 - 音响
class Stereo {
private:
std::string location;
int volume;

public:
explicit Stereo(const std::string& location) : location(location), volume(0) {}

void on() {
std::cout << location << " 音响已打开\n";
}

void off() {
std::cout << location << " 音响已关闭\n";
}

void setCD() {
std::cout << location << " 音响已设置为CD模式\n";
}

void setVolume(int level) {
volume = level;
std::cout << location << " 音响音量设置为 " << volume << "\n";
}
};

// 具体命令类 - 打开音响
class StereoOnWithCDCommand : public Command {
private:
std::shared_ptr<Stereo> stereo;

public:
explicit StereoOnWithCDCommand(std::shared_ptr<Stereo> stereo) : stereo(stereo) {}

void execute() override {
stereo->on();
stereo->setCD();
stereo->setVolume(11);
}

void undo() override {
stereo->off();
}
};

// 调用者类 - 遥控器
class RemoteControl {
private:
std::vector<std::shared_ptr<Command>> onCommands;
std::vector<std::shared_ptr<Command>> offCommands;
std::shared_ptr<Command> undoCommand;

public:
RemoteControl() {
onCommands.resize(7);
offCommands.resize(7);

// 初始化空命令
auto noCommand = std::make_shared<LightOnCommand>(std::make_shared<Light>("空"));
for (int i = 0; i < 7; i++) {
onCommands[i] = noCommand;
offCommands[i] = noCommand;
}
undoCommand = noCommand;
}

void setCommand(int slot, std::shared_ptr<Command> onCommand, std::shared_ptr<Command> offCommand) {
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
}

void onButtonWasPushed(int slot) {
onCommands[slot]->execute();
undoCommand = onCommands[slot];
}

void offButtonWasPushed(int slot) {
offCommands[slot]->execute();
undoCommand = offCommands[slot];
}

void undoButtonWasPushed() {
undoCommand->undo();
}

void print() const {
std::cout << "\n------ 遥控器 ------\n";
for (size_t i = 0; i < onCommands.size(); i++) {
std::cout << "[slot " << i << "] ";
// 注意:这里简化处理,实际项目中可能需要更复杂的类型识别
}
std::cout << "\n";
}
};

// 客户端代码
int main() {
RemoteControl remote;

// 创建设备
auto livingRoomLight = std::make_shared<Light>("客厅");
auto kitchenLight = std::make_shared<Light>("厨房");
auto stereo = std::make_shared<Stereo>("客厅");

// 创建命令
auto livingRoomLightOn = std::make_shared<LightOnCommand>(livingRoomLight);
auto livingRoomLightOff = std::make_shared<LightOffCommand>(livingRoomLight);
auto kitchenLightOn = std::make_shared<LightOnCommand>(kitchenLight);
auto kitchenLightOff = std::make_shared<LightOffCommand>(kitchenLight);
auto stereoOn = std::make_shared<StereoOnWithCDCommand>(stereo);
auto stereoOff = std::make_shared<LightOffCommand>(std::make_shared<Light>("空")); // 简化处理

// 设置遥控器插槽
remote.setCommand(0, livingRoomLightOn, livingRoomLightOff);
remote.setCommand(1, kitchenLightOn, kitchenLightOff);
remote.setCommand(2, stereoOn, stereoOff);

// 测试遥控器
std::cout << "=== 遥控器测试 ===\n";
remote.onButtonWasPushed(0);
remote.offButtonWasPushed(0);
remote.onButtonWasPushed(1);
remote.offButtonWasPushed(1);
remote.onButtonWasPushed(2);
remote.undoButtonWasPushed();

return 0;
}

命令模式的关键组成部分

  1. Command(命令接口)

    • 定义执行操作的接口,通常包含 execute()undo() 方法
  2. ConcreteCommand(具体命令)

    • 实现 Command 接口
    • LightOnCommandLightOffCommand 是具体命令实现
  3. Receiver(接收者)

    • 知道如何执行一个请求的相关操作
    • LightStereo 类是接收者
  4. Invoker(调用者)

    • 要求该命令执行这个请求
    • RemoteControl 类是调用者
  5. Client(客户端)

    • 创建具体命令对象并设置其接收者
    • main 函数扮演客户端角色

命令模式的优点

  • 解耦:将调用操作的对象与知道如何执行该操作的对象解耦
  • 扩展性:容易设计一个命令队列和宏命令
  • 可撤销操作:通过 undo() 方法可以实现撤销功能
  • 易于添加新命令:符合开闭原则

这个示例展示了如何使用命令模式实现一个简单的遥控器系统,支持多种设备控制和撤销操作。