我将为您创建一个命令模式的完整示例。命令模式是一种行为设计模式,它将请求封装成对象,从而使您可以用不同的请求对客户进行参数化。
命令模式示例代码
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; }
|
命令模式的关键组成部分
Command(命令接口):
- 定义执行操作的接口,通常包含
execute() 和 undo() 方法
ConcreteCommand(具体命令):
- 实现
Command 接口
LightOnCommand 和 LightOffCommand 是具体命令实现
Receiver(接收者):
- 知道如何执行一个请求的相关操作
Light 和 Stereo 类是接收者
Invoker(调用者):
- 要求该命令执行这个请求
RemoteControl 类是调用者
Client(客户端):
- 创建具体命令对象并设置其接收者
main 函数扮演客户端角色
命令模式的优点
- 解耦:将调用操作的对象与知道如何执行该操作的对象解耦
- 扩展性:容易设计一个命令队列和宏命令
- 可撤销操作:通过
undo() 方法可以实现撤销功能
- 易于添加新命令:符合开闭原则
这个示例展示了如何使用命令模式实现一个简单的遥控器系统,支持多种设备控制和撤销操作。