linux开发

命令模式

命令模式的封面

我将为您创建一个命令模式的完整示例。命令模式是一种行为设计模式,它将请求封装成对象,从而使您可以用不同的请求对客户进行参数化。

命令模式示例代码

#include <iostream>
#include <vector>
#include <memory>

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

// 接收者类 - 灯
class Light {
private:
    std::string location;
    bool isOn;

public:
    explicit Light(const std::string& location) : location(location), isOn(false) {}

    void turnOn() {
        isOn = true;
        std::cout << location << " 灯已打开\n";
    }

    void turnOff() {
        isOn = false;
        std::cout << location << " 灯已关闭\n";
    }

    bool getState() const {
        return isOn;
    }
};

// 具体命令类 - 打开灯
class LightOnCommand : public Command {
private:
    std::shared_ptr<Light> light;

public:
    explicit LightOnCommand(std::shared_ptr<Light> light) : light(light) {}

    void execute() override {
        light->turnOn();
    }

    void undo() override {
        light->turnOff();
    }
};

// 具体命令类 - 关闭灯
class LightOffCommand : public Command {
private:
    std::shared_ptr<Light> light;

public:
    explicit LightOffCommand(std::shared_ptr<Light> light) : light(light) {}

    void execute() override {
        light->turnOff();
    }

    void undo() override {
        light->turnOn();
    }
};

// 接收者类 - 音响
class Stereo {
private:
    std::string location;
    int volume;

public:
    explicit Stereo(const std::string& location) : location(location), volume(0) {}

    void on() {
        std::cout << location << " 音响已打开\n";
    }

    void off() {
        std::cout << location << " 音响已关闭\n";
    }

    void setCD() {
        std::cout << location << " 音响已设置为CD模式\n";
    }

    void setVolume(int level) {
        volume = level;
        std::cout << location << " 音响音量设置为 " << volume << "\n";
    }
};

// 具体命令类 - 打开音响
class StereoOnWithCDCommand : public Command {
private:
    std::shared_ptr<Stereo> stereo;

public:
    explicit StereoOnWithCDCommand(std::shared_ptr<Stereo> stereo) : stereo(stereo) {}

    void execute() override {
        stereo->on();
        stereo->setCD();
        stereo->setVolume(11);
    }

    void undo() override {
        stereo->off();
    }
};

// 调用者类 - 遥控器
class RemoteControl {
private:
    std::vector<std::shared_ptr<Command>> onCommands;
    std::vector<std::shared_ptr<Command>> offCommands;
    std::shared_ptr<Command> undoCommand;

public:
    RemoteControl() {
        onCommands.resize(7);
        offCommands.resize(7);
        
        // 初始化空命令
        auto noCommand = std::make_shared<LightOnCommand>(std::make_shared<Light>("空"));
        for (int i = 0; i < 7; i++) {
            onCommands[i] = noCommand;
            offCommands[i] = noCommand;
        }
        undoCommand = noCommand;
    }

    void setCommand(int slot, std::shared_ptr<Command> onCommand, std::shared_ptr<Command> offCommand) {
        onCommands[slot] = onCommand;
        offCommands[slot] = offCommand;
    }

    void onButtonWasPushed(int slot) {
        onCommands[slot]->execute();
        undoCommand = onCommands[slot];
    }

    void offButtonWasPushed(int slot) {
        offCommands[slot]->execute();
        undoCommand = offCommands[slot];
    }

    void undoButtonWasPushed() {
        undoCommand->undo();
    }

    void print() const {
        std::cout << "\n------ 遥控器 ------\n";
        for (size_t i = 0; i < onCommands.size(); i++) {
            std::cout << "[slot " << i << "] ";
            // 注意:这里简化处理,实际项目中可能需要更复杂的类型识别
        }
        std::cout << "\n";
    }
};

// 客户端代码
int main() {
    RemoteControl remote;
    
    // 创建设备
    auto livingRoomLight = std::make_shared<Light>("客厅");
    auto kitchenLight = std::make_shared<Light>("厨房");
    auto stereo = std::make_shared<Stereo>("客厅");
    
    // 创建命令
    auto livingRoomLightOn = std::make_shared<LightOnCommand>(livingRoomLight);
    auto livingRoomLightOff = std::make_shared<LightOffCommand>(livingRoomLight);
    auto kitchenLightOn = std::make_shared<LightOnCommand>(kitchenLight);
    auto kitchenLightOff = std::make_shared<LightOffCommand>(kitchenLight);
    auto stereoOn = std::make_shared<StereoOnWithCDCommand>(stereo);
    auto stereoOff = std::make_shared<LightOffCommand>(std::make_shared<Light>("空")); // 简化处理
    
    // 设置遥控器插槽
    remote.setCommand(0, livingRoomLightOn, livingRoomLightOff);
    remote.setCommand(1, kitchenLightOn, kitchenLightOff);
    remote.setCommand(2, stereoOn, stereoOff);
    
    // 测试遥控器
    std::cout << "=== 遥控器测试 ===\n";
    remote.onButtonWasPushed(0);
    remote.offButtonWasPushed(0);
    remote.onButtonWasPushed(1);
    remote.offButtonWasPushed(1);
    remote.onButtonWasPushed(2);
    remote.undoButtonWasPushed();
    
    return 0;
}

命令模式的关键组成部分

  1. Command(命令接口):

    • 定义执行操作的接口,通常包含 execute() 和 undo() 方法
  2. ConcreteCommand(具体命令):

    • 实现 Command 接口
    • LightOnCommand 和 LightOffCommand 是具体命令实现
  3. Receiver(接收者):

    • 知道如何执行一个请求的相关操作
    • Light 和 Stereo 类是接收者
  4. Invoker(调用者):

    • 要求该命令执行这个请求
    • RemoteControl 类是调用者
  5. Client(客户端):

    • 创建具体命令对象并设置其接收者
    • main 函数扮演客户端角色

命令模式的优点

  • 解耦:将调用操作的对象与知道如何执行该操作的对象解耦
  • 扩展性:容易设计一个命令队列和宏命令
  • 可撤销操作:通过 undo() 方法可以实现撤销功能
  • 易于添加新命令:符合开闭原则

这个示例展示了如何使用命令模式实现一个简单的遥控器系统,支持多种设备控制和撤销操作。