| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- #ifndef __COMMANDMODEL_H__
- #define __COMMANDMODEL_H__
- #include "spdlog/spdlog.h"
- #include <map>
- #include <list>
- /**
- 命令模式
- 定义:将一个请求封装为一个对象,从而使您可以用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
- 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<int, std::list<AbstractCommand*>> m_commands;
- /* 可撤销的命令(已执行过的) */
- std::map<int, AbstractCommand*> m_undoCommands;
- };
- /* 使用遥控器 */
- void useRemoteControl();
- }
- #endif /* __COMMANDMODEL_H__ */
|