命令模式
1.何为命令模式
将一个请求封装为一个对象,向对象发送命令来指导它们做事,从而可用不同的请求来指导对象不同的行为。如此可以实现请求排队、记录请求日志、撤销请求、事务等操作。实现“行为”和“组件”的解耦。
2.命令模式的意义和使用场景
在软件构建过程中,行为请求者和行为实现者通常是紧耦合关系,但在某些场合需要对请求进行记录、撤销、事务等操作,这种耦合是不合适的。所以将操作指令封装为一个命令对象,用于对象之间的通信,比通过函数参数通信更方便、灵活。
3.命令模式的实现
设计一个命令抽象基类,然后通过继承实现各种命令。也可以实现复合命令,即命令对象中用一个数组存放命令集。还可以将 查询命令和请求命令分开,就像sql一样。
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
| class Command { public: virtual void execute() = 0; virtual void undo() = 0; };
class Light { public: void turnOn() { std::cout << "Light is ON" << std::endl; }
void turnOff() { std::cout << "Light is OFF" << std::endl; } };
class TurnOnLightCommand : public Command { private: Light& light; string args; public: TurnOnLightCommand(Light& l,arg) : light(l),args(arg) {} void execute() override { light.turnOn(); } void undo() override { light.turnOff(); } };
class TurnOffLightCommand : public Command { private: Light& light; string args; public: TurnOffLightCommand(Light& l) : light(l),args(arg) {}
void execute() override { light.turnOff(); } void undo() override { light.turnOn(); } };
class LightCommands : public Command { private: vector<Command*> commands; public: TurnOffLightCommand() {} void addcommand(Command* cmd) void execute() override { for(auto i : commands) { i->execute(); } } };
|
需要指出的是,在c++中由于性能的需求,实际应用中,许多命令模式被范式编程+仿函数代替。命令模式用接口-实现来定义行为接口规范,更严格,但性能有所损失。函数对象(仿函数)以函数签名定义行为规范,更灵活,性能高。