命令模式 (Command Pattern)

命令模式 (Command Pattern)

意图:将请求封装为一个对象,从而可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。

基础组件
  • Command (命令):声明执行操作的接口
  • ConcreteCommand (具体命令):将接收者绑定到动作,实现执行方法
  • Invoker (调用者):要求命令执行请求
  • Receiver (接收者):知道如何执行与请求相关的操作
  • Client (客户端):创建具体命令并设置其接收者
继承/实现关系
Command <|-- ConcreteCommand
ConcreteCommand --> Receiver (调用接收者执行操作)
Invoker --> Command (聚合命令)
Client --> ConcreteCommand (创建)
Client --> Receiver (创建)
应用场景
  • 需要将请求参数化
  • 需要支持操作队列、撤销/重做
  • 需要支持日志功能(记录命令历史)
C++ 实现(智能家居控制)
#include <iostream>
#include <string>
#include <vector>
#include <memory>

/*
* 命令模式
* 意图:将请求封装为一个对象,从而可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
* 基础组件:
* Command (命令):声明执行操作的接口
* ConcreteCommand (具体命令):将接收者绑定到动作,实现执行方法
* Invoker (调用者):要求命令执行请求
* Receiver (接收者):知道如何执行与请求相关的操作
* Client (客户端):创建具体命令并设置其接收者
* 继承/实现关系:
* ConcreteCommand 继承自 Command
* Invoker 持有 Command 的引用
* Client 创建 ConcreteCommand 的实例并设置其接收者(Receiver)
*/

// 接收者:灯光
class Light {
public:
    void on() {
        state_ = true;
        std::cout << "Light is on\n";
    }

    void off() {
        state_ = false;
        std::cout << "Light is off\n";
    }

    bool getState() const { return state_; }

private:
    bool state_ = false;
};

// 接收者:空调
class AirConditioner {
public:
    void setTemperature(int temp) {
        temperature_ = temp;
        std::cout << "AC set to " << temp << "°C\n";
    }

    int getTemperature() const { return temperature_; }

private:
    int temperature_ = 25;
};

// 命令接口
class Command {
public:
    virtual ~Command() = default;
    virtual void execute() = 0;
    virtual void undo() = 0;
    virtual std::unique_ptr<Command> clone() = 0;
};

// 具体命令:开灯
class LightOnCommand : public Command {
public:
    explicit LightOnCommand(Light* light) : light_(light) {}

    void execute() override {
        prevState_ = light_->getState();
        light_->on();
    }

    void undo() override {
        if (!prevState_) {
            light_->off();
        }
    }

    std::unique_ptr<Command> clone() override {
        return std::make_unique<LightOnCommand>(*this);
    }

private:
    Light* light_;
    bool prevState_ = false;
};

// 具体命令:关灯
class LightOffCommand : public Command {
public:
    explicit LightOffCommand(Light* light) : light_(light) {}

    void execute() override {
        prevState_ = light_->getState();
        light_->off();
    }

    void undo() override {
        if (prevState_) {
            light_->on();
        }
    }
    std::unique_ptr<Command> clone() override {
        return std::make_unique<LightOffCommand>(*this);
    }

private:
    Light* light_;
    bool prevState_ = false;
};

// 具体命令:设置空调温度
class SetTemperatureCommand : public Command {
public:
    SetTemperatureCommand(AirConditioner* ac, int temp)
        : ac_(ac), temp_(temp) {}

    void execute() override {
        prevTemp_ = ac_->getTemperature();
        ac_->setTemperature(temp_);
    }

    void undo() override {
        ac_->setTemperature(prevTemp_);
    }

    std::unique_ptr<Command> clone() override {
        return std::make_unique<SetTemperatureCommand>(*this);
    }

private:
    AirConditioner* ac_;
    int temp_;
    int prevTemp_;
};

// 调用者:遥控器
class RemoteControl {
public:
    void setCommand(std::unique_ptr<Command> cmd) {
        command_ = std::move(cmd);
    }

    void pressButton() {
        if (command_) {
            command_->execute();
            history_.push_back(command_->clone());
        }
    }

    void pressUndo() {
        if (!history_.empty()) {
            history_.back()->undo();
            history_.pop_back();
        }
    }

private:
    std::unique_ptr<Command> command_;
    std::vector<std::unique_ptr<Command>> history_;
};

void CommandPattern()
{
	std::cout << std::string(13, '-') << " Command Pattern " << std::string(13, '-') << std::endl;
	
    // 创建接收者
    Light livingRoomLight;
    AirConditioner bedroomAC;

    // 创建命令
    auto lightOn = std::make_unique<LightOnCommand>(&livingRoomLight);
    auto lightOff = std::make_unique<LightOffCommand>(&livingRoomLight);
    auto setAC = std::make_unique<SetTemperatureCommand>(&bedroomAC, 22);

    // 创建调用者
    RemoteControl remote;

    // 开灯
    remote.setCommand(std::move(lightOn));
    remote.pressButton();

    // 设置空调温度
    remote.setCommand(std::move(setAC));
    remote.pressButton();

    // 关灯
    remote.setCommand(std::move(lightOff));
    remote.pressButton();

    // 撤销最后一步操作(关灯)
    remote.pressUndo();
}
组件对应关系
  • Command → 命令接口
  • LightOnCommand/LightOffCommand/SetTemperatureCommand → 具体命令
  • Light/AirConditioner → 接收者
  • RemoteControl → 调用者
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值