C++命令模式(Command)

让我们用一个简单易懂的日常生活例子来解释命令模式(Command Pattern)。假设有一个智能家居系统,可以通过语音助手来控制各类家电,如电视、灯和音响。这些家电可以接受不同的命令,比如打开、关闭、调节音量或亮度等。命令模式可以帮助我们更好地实现这一系统。

生活中的实际应用:智能家居系统

假设你有一个智能家居系统,可以通过语音助手来控制家中的设备。每个家电都可以接受特定的命令,如打开、关闭、调节等。为了让系统更易于维护和扩展,我们可以使用命令模式。

主要角色
  1. 客户(Client):创建具体命令对象并设置其接收者。
  2. 命令接口(Command):定义一个执行操作的接口。
  3. 具体命令(ConcreteCommand):实现命令接口,执行具体的操作。
  4. 调用者(Invoker):持有命令对象并在某个时间点执行命令。
  5. 接收者(Receiver):真正执行命令的对象。

编码示例

下面的代码使用命令模式来实现智能家居中的设备控制。

#include <iostream>
#include <vector>

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

// 具体命令:打开电视
class TV {
public:
    void on() {
        std::cout << "电视打开了" << std::endl;
    }
    void off() {
        std::cout << "电视关闭了" << std::endl;
    }
};

class TVOnCommand : public Command {
private:
    TV* tv;

public:
    TVOnCommand(TV* t) : tv(t) {}
    
    void execute() override {
        tv->on();
    }
    
    void undo() override {
        tv->off();
    }
};

// 具体命令:打开灯
class Light {
public:
    void on() {
        std::cout << "灯打开了" << std::endl;
    }
    void off() {
        std::cout << "灯关闭了" << std::endl;
    }
};

class LightOnCommand : public Command {
private:
    Light* light;

public:
    LightOnCommand(Light* l) : light(l) {}
    
    void execute() override {
        light->on();
    }
    
    void undo() override {
        light->off();
    }
};

// 调用者:遥控器
class RemoteControl {
private:
    Command* command;
    std::vector<Command*> history;

public:
    void setCommand(Command* cmd) {
        command = cmd;
    }
    
    void pressButton() {
        if (command) {
            command->execute();
            history.push_back(command);
        }
    }

    void pressUndo() {
        if (!history.empty()) {
            Command* cmd = history.back();
            history.pop_back();
            cmd->undo();
        }
    }
};

// 主函数
int main() {
    // 创建接收者
    TV* tv = new TV();
    Light* light = new Light();

    // 创建具体命令
    Command* tvOnCommand = new TVOnCommand(tv);
    Command* lightOnCommand = new LightOnCommand(light);

    // 创建调用者
    RemoteControl* remote = new RemoteControl();

    // 设置并执行命令
    remote->setCommand(tvOnCommand);
    remote->pressButton();

    remote->setCommand(lightOnCommand);
    remote->pressButton();

    // 撤销操作
    remote->pressUndo();
    remote->pressUndo();

    // 释放资源
    delete tvOnCommand;
    delete lightOnCommand;
    delete tv;
    delete light;
    delete remote;

    return 0;
}

代码解释

  1. 命令接口 (Command):定义了两个方法 execute() 和 undo(),用于执行和撤销操作。
  2. 具体命令 (TVOnCommand 和 LightOnCommand):每个具体命令都持有一个接收者对象(如 TV 或 Light),并在 execute() 和 undo() 方法中调用接收者的具体操作。
  3. 接收者 (TV 和 Light):实现具体的操作,如打开和关闭设备。
  4. 调用者 (RemoteControl):持有命令对象,调用 execute() 方法执行操作,并记录每次执行的命令以支持撤销操作(undo())。

总结

命令模式将请求封装为对象,从而使你可以用不同的请求对客户进行参数化。通过这个示例,我们可以看到命令模式的优点:

  • 解耦调用者和接收者:调用者(RemoteControl)不需要知道如何执行命令,只需要调用命令对象的 execute() 方法。
  • 可扩展性:添加新命令非常容易,只需继承命令接口并实现 execute() 和 undo() 方法。
  • 支持撤销操作:通过记录执行过的命令,可以轻松实现操作的撤销。
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值