#ifndef __COMMANDMODEL_H__ #define __COMMANDMODEL_H__ #include "spdlog/spdlog.h" #include #include /** 命令模式 定义:将一个请求封装为一个对象,从而使您可以用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。 UML类图: Client(客户端) │ Invoker(调用者) │ Command(抽象命令) │ ┌───┴──────────┐ ConcreteCommandA ConcreteCommandB(具体命令) │ Receiver(接收者) 角色: Command(命令接口):定义 execute() 方法,封装执行逻辑。 ConcreteCommand(具体命令):实现 Command,并持有 Receiver,调用其方法执行具体操作。 Receiver(接收者):实际执行操作的对象,提供具体的功能实现。 Invoker(调用者):持有 Command 对象,触发 execute(),可以支持命令队列、撤销等功能。 Client(客户端):创建 Command 对象,并将其传递给 Invoker。 优点: 1、降低了命令的发起者与命令的执行者之间的耦合度。 2、新的命令可以很容易地加入到系统中。 3、可以比较容易地设计一个命令队列和宏命令。 4、可以方便地实现对请求的撤销和重做。 缺点: 1、使用命令模式可能会导致某些系统有过多的具体命令类。 适用场景: 1、系统需要将请求调用者与请求接收者解耦时。 2、系统需要支持命令的撤销(Undo)和重做(Redo)操作时。 3、系统需要将一组操作组合在一起,即支持宏命令(Macro Command)时。 示例: 使用命令模式实现只能家居 */ namespace CommandModel { /* ========================================================= * 命令接收者,这里是设置,会有多个具体的接收者 * ========================================================= */ /* 灯光 */ class Light { public: void on() { SPDLOG_INFO("灯光已打开"); } void off() { SPDLOG_INFO("灯光已关闭"); } }; class TV { public: void on() { SPDLOG_INFO("电视已打开"); } void off() { SPDLOG_INFO("电视已关闭"); } }; /* ========================================================= * 命令接口 * ========================================================= */ /* 抽象命令 */ class AbstractCommand { public: virtual ~AbstractCommand() = default; virtual void execute() = 0; virtual void undo() = 0; }; /* 开灯命令 */ class LightOnCommand : public AbstractCommand { public: LightOnCommand(Light* light) : m_light(light) {} void execute() override { m_light->on(); } void undo() override { m_light->off(); } private: Light* m_light; }; /* 关灯命令 */ class LightOffCommand : public AbstractCommand { public: LightOffCommand(Light* light) : m_light(light) {} void execute() override { m_light->off(); } void undo() override { m_light->on(); } private: Light* m_light; }; /* 开电视命令 */ class TVOnCommand : public AbstractCommand { public: TVOnCommand(TV* tv) : m_tv(tv) {} void execute() override { m_tv->on(); } void undo() override { m_tv->off(); } private: TV* m_tv; }; /* 关电视命令 */ class TVOffCommand : public AbstractCommand { public: TVOffCommand(TV* tv) : m_tv(tv) {} void execute() override { m_tv->off(); } void undo() override { m_tv->on(); } private: TV* m_tv; }; /* ========================================================= * 调用者,这里是遥控器,这个遥控器是万能遥控器,可以控制所有设备 * ========================================================= */ /* 遥控器设备 */ class RemoteControl { public: /* 设置命令(添加命令) */ void setCommand(int slot, AbstractCommand* command); /* 执行命令 */ void pressButton(int dev); /* 撤销命令 */ void pressUndo(int dev, int count = 1); private: /* 即将要执行的命令列表 */ std::map> m_commands; /* 可撤销的命令(已执行过的) */ std::map m_undoCommands; }; /* 使用遥控器 */ void useRemoteControl(); } #endif /* __COMMANDMODEL_H__ */