第十五章:令行禁止,运筹帷幄——Command的命令艺术

第十五章:令行禁止,运筹帷幄------Command的命令艺术

风云再起,命令将军登场

在Strategy展示完他那精妙的策略艺术后,Command令行禁止、宛如将军般走出。他腰挂令牌,目光如炬,每个动作都透露出威严与秩序。

"Strategy兄的算法选择确实精妙,"Command声如洪钟地说道,"但在请求封装和执行控制方面,需要更加统一的处理方式。诸位请看------"

Command从腰间取下一枚令牌,令牌在空中化作一道流光:"我的命令模式,专为解决请求的封装和执行问题而生!我将请求封装成对象,从而支持请求的队列、日志、撤销和重做操作!"

架构老人眼中闪过赞许之色:"善!Command,就请你为大家展示这命令艺术的精妙所在。"

命令模式的核心要义

Command面向众人,开始阐述他的武学真谛:

"在我的命令模式中,主要包含四个核心角色:"

"Command(命令):声明执行操作的接口。"

"ConcreteCommand(具体命令):将一个接收者对象绑定于一个动作,实现执行方法。"

"Invoker(调用者):要求命令执行请求。"

"Receiver(接收者):知道如何实施与执行一个请求相关的操作。"

"其精妙之处在于,"Command继续道,"命令对象将动作和接收者包进对象中,只暴露一个execute()方法。这样,命令对象可以被存储、传递、调用,甚至支持撤销和重做!"

C++实战:智能家居控制系统

"且让我以一个智能家居控制系统为例,展示命令模式的实战应用。"Command说着,手中凝聚出一道道代码流光。

基础框架搭建

首先,Command定义了命令接口:

cpp 复制代码
#include <iostream>
#include <vector>
#include <string>
#include <memory>
#include <algorithm>
#include <map>
#include <iomanip>
#include <sstream>
#include <random>
#include <thread>
#include <chrono>
#include <stack>
#include <queue>

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

// 命令历史管理器
class CommandHistory {
private:
    std::stack<std::unique_ptr<Command>> history_;
    std::stack<std::unique_ptr<Command>> redoStack_;
    
public:
    CommandHistory() {
        std::cout << "📜 创建命令历史管理器" << std::endl;
    }
    
    void push(std::unique_ptr<Command> command) {
        history_.push(std::move(command));
        // 执行新命令时清空重做栈
        while (!redoStack_.empty()) {
            redoStack_.pop();
        }
        std::cout << "📝 记录命令到历史" << std::endl;
    }
    
    void undo() {
        if (history_.empty()) {
            std::cout << "❌ 没有可撤销的命令" << std::endl;
            return;
        }
        
        auto command = std::move(history_.top());
        history_.pop();
        
        std::cout << "↩️  撤销命令: " << command->getName() << std::endl;
        command->undo();
        
        redoStack_.push(std::move(command));
    }
    
    void redo() {
        if (redoStack_.empty()) {
            std::cout << "❌ 没有可重做的命令" << std::endl;
            return;
        }
        
        auto command = std::move(redoStack_.top());
        redoStack_.pop();
        
        std::cout << "↪️  重做命令: " << command->getName() << std::endl;
        command->execute();
        
        history_.push(std::move(command));
    }
    
    void clear() {
        while (!history_.empty()) history_.pop();
        while (!redoStack_.empty()) redoStack_.pop();
        std::cout << "🧹 清空命令历史" << std::endl;
    }
    
    size_t getHistorySize() const { return history_.size(); }
    size_t getRedoSize() const { return redoStack_.size(); }
    
    void showStatus() const {
        std::cout << "📊 命令历史状态: " << history_.size() 
                  << " 个已执行, " << redoStack_.size() << " 个可重做" << std::endl;
    }
};

接收者实现

Command创建了各种智能家居设备:

cpp 复制代码
// 接收者:灯光
class Light {
private:
    std::string location_;
    bool isOn_;
    int brightness_; // 0-100
    std::string color_;
    
public:
    Light(const std::string& location) 
        : location_(location), isOn_(false), brightness_(50), color_("white") {
        std::cout << "💡 创建灯光: " << location_ << std::endl;
    }
    
    void on() {
        isOn_ = true;
        std::cout << "🔆 " << location_ << " 灯光打开" << std::endl;
    }
    
    void off() {
        isOn_ = false;
        std::cout << "🌙 " << location_ << " 灯光关闭" << std::endl;
    }
    
    void setBrightness(int level) {
        brightness_ = std::max(0, std::min(100, level));
        std::cout << "☀️  " << location_ << " 亮度设置为: " << brightness_ << "%" << std::endl;
    }
    
    void setColor(const std::string& color) {
        color_ = color;
        std::cout << "🎨 " << location_ << " 颜色设置为: " << color_ << std::endl;
    }
    
    void dim() {
        brightness_ = std::max(0, brightness_ - 10);
        std::cout << "🔅 " << location_ << " 调暗到: " << brightness_ << "%" << std::endl;
    }
    
    void brighten() {
        brightness_ = std::min(100, brightness_ + 10);
        std::cout << "🔆 " << location_ << " 调亮到: " << brightness_ << "%" << std::endl;
    }
    
    std::string getStatus() const {
        std::stringstream ss;
        ss << location_ << " 灯光: " << (isOn_ ? "开" : "关")
           << " | 亮度: " << brightness_ << "%"
           << " | 颜色: " << color_;
        return ss.str();
    }
    
    bool isOn() const { return isOn_; }
    int getBrightness() const { return brightness_; }
    std::string getColor() const { return color_; }
    std::string getLocation() const { return location_; }
};

// 接收者:空调
class AirConditioner {
private:
    std::string location_;
    bool isOn_;
    int temperature_; // 摄氏度
    int fanSpeed_;    // 1-5
    std::string mode_; // "cool", "heat", "fan", "auto"
    
public:
    AirConditioner(const std::string& location) 
        : location_(location), isOn_(false), temperature_(22), fanSpeed_(3), mode_("cool") {
        std::cout << "❄️  创建空调: " << location_ << std::endl;
    }
    
    void on() {
        isOn_ = true;
        std::cout << "🌀 " << location_ << " 空调打开" << std::endl;
    }
    
    void off() {
        isOn_ = false;
        std::cout << "💤 " << location_ << " 空调关闭" << std::endl;
    }
    
    void setTemperature(int temp) {
        temperature_ = std::max(16, std::min(30, temp));
        std::cout << "🌡️  " << location_ << " 温度设置为: " << temperature_ << "°C" << std::endl;
    }
    
    void setFanSpeed(int speed) {
        fanSpeed_ = std::max(1, std::min(5, speed));
        std::cout << "💨 " << location_ << " 风速设置为: " << fanSpeed_ << std::endl;
    }
    
    void setMode(const std::string& mode) {
        mode_ = mode;
        std::cout << "🎛️  " << location_ << " 模式设置为: " << mode_ << std::endl;
    }
    
    void increaseTemp() {
        temperature_ = std::min(30, temperature_ + 1);
        std::cout << "🌡️  " << location_ << " 温度升高到: " << temperature_ << "°C" << std::endl;
    }
    
    void decreaseTemp() {
        temperature_ = std::max(16, temperature_ - 1);
        std::cout << "🌡️  " << location_ << " 温度降低到: " << temperature_ << "°C" << std::endl;
    }
    
    std::string getStatus() const {
        std::stringstream ss;
        ss << location_ << " 空调: " << (isOn_ ? "开" : "关")
           << " | 温度: " << temperature_ << "°C"
           << " | 风速: " << fanSpeed_
           << " | 模式: " << mode_;
        return ss.str();
    }
    
    bool isOn() const { return isOn_; }
    int getTemperature() const { return temperature_; }
    int getFanSpeed() const { return fanSpeed_; }
    std::string getMode() const { return mode_; }
};

// 接收者:窗帘
class Curtain {
private:
    std::string location_;
    bool isOpen_;
    int position_; // 0-100, 0=完全关闭, 100=完全打开
    
public:
    Curtain(const std::string& location) 
        : location_(location), isOpen_(false), position_(0) {
        std::cout << "🪟 创建窗帘: " << location_ << std::endl;
    }
    
    void open() {
        isOpen_ = true;
        position_ = 100;
        std::cout << "🌅 " << location_ << " 窗帘打开" << std::endl;
    }
    
    void close() {
        isOpen_ = false;
        position_ = 0;
        std::cout << "🌃 " << location_ << " 窗帘关闭" << std::endl;
    }
    
    void setPosition(int pos) {
        position_ = std::max(0, std::min(100, pos));
        isOpen_ = (position_ > 0);
        std::cout << "🎚️  " << location_ << " 窗帘位置: " << position_ << "%" << std::endl;
    }
    
    void openPartially(int percent) {
        setPosition(percent);
        std::cout << "🪟 " << location_ << " 部分打开: " << percent << "%" << std::endl;
    }
    
    std::string getStatus() const {
        std::stringstream ss;
        ss << location_ << " 窗帘: " << (isOpen_ ? "开" : "关")
           << " | 位置: " << position_ << "%";
        return ss.str();
    }
    
    bool isOpen() const { return isOpen_; }
    int getPosition() const { return position_; }
};

// 接收者:音响系统
class Stereo {
private:
    std::string location_;
    bool isOn_;
    int volume_; // 0-100
    std::string source_; // "CD", "Radio", "Bluetooth", "Aux"
    
public:
    Stereo(const std::string& location) 
        : location_(location), isOn_(false), volume_(30), source_("Radio") {
        std::cout << "🔊 创建音响: " << location_ << std::endl;
    }
    
    void on() {
        isOn_ = true;
        std::cout << "🎵 " << location_ << " 音响打开" << std::endl;
    }
    
    void off() {
        isOn_ = false;
        std::cout << "🔇 " << location_ << " 音响关闭" << std::endl;
    }
    
    void setVolume(int level) {
        volume_ = std::max(0, std::min(100, level));
        std::cout << "🔊 " << location_ << " 音量设置为: " << volume_ << std::endl;
    }
    
    void setSource(const std::string& src) {
        source_ = src;
        std::cout << "📻 " << location_ << " 音源设置为: " << source_ << std::endl;
    }
    
    void volumeUp() {
        volume_ = std::min(100, volume_ + 5);
        std::cout << "🔊 " << location_ << " 音量增加到: " << volume_ << std::endl;
    }
    
    void volumeDown() {
        volume_ = std::max(0, volume_ - 5);
        std::cout << "🔊 " << location_ << " 音量减少到: " << volume_ << std::endl;
    }
    
    std::string getStatus() const {
        std::stringstream ss;
        ss << location_ << " 音响: " << (isOn_ ? "开" : "关")
           << " | 音量: " << volume_
           << " | 音源: " << source_;
        return ss.str();
    }
    
    bool isOn() const { return isOn_; }
    int getVolume() const { return volume_; }
    std::string getSource() const { return source_; }
};

具体命令实现

Command创建了各种设备命令:

cpp 复制代码
// 具体命令:灯光命令
class LightCommand : public Command {
protected:
    Light& light_;
    std::string name_;
    
public:
    LightCommand(Light& light, const std::string& name) 
        : light_(light), name_(name) {}
    
    std::string getName() const override {
        return name_;
    }
    
    std::string getDescription() const override {
        return "控制 " + light_.getLocation() + " 灯光";
    }
};

class LightOnCommand : public LightCommand {
private:
    int previousBrightness_;
    std::string previousColor_;
    bool wasOn_;
    
public:
    LightOnCommand(Light& light) : LightCommand(light, "打开灯光") {
        wasOn_ = light_.isOn();
        previousBrightness_ = light_.getBrightness();
        previousColor_ = light_.getColor();
    }
    
    void execute() override {
        std::cout << "🚀 执行: " << getName() << std::endl;
        wasOn_ = light_.isOn();
        previousBrightness_ = light_.getBrightness();
        previousColor_ = light_.getColor();
        
        light_.on();
        light_.setBrightness(80); // 默认亮度
        light_.setColor("white"); // 默认颜色
    }
    
    void undo() override {
        std::cout << "↩️  撤销: " << getName() << std::endl;
        if (!wasOn_) {
            light_.off();
        }
        light_.setBrightness(previousBrightness_);
        light_.setColor(previousColor_);
    }
};

class LightOffCommand : public LightCommand {
private:
    int previousBrightness_;
    std::string previousColor_;
    bool wasOn_;
    
public:
    LightOffCommand(Light& light) : LightCommand(light, "关闭灯光") {
        wasOn_ = light_.isOn();
        previousBrightness_ = light_.getBrightness();
        previousColor_ = light_.getColor();
    }
    
    void execute() override {
        std::cout << "🚀 执行: " << getName() << std::endl;
        wasOn_ = light_.isOn();
        previousBrightness_ = light_.getBrightness();
        previousColor_ = light_.getColor();
        
        light_.off();
    }
    
    void undo() override {
        std::cout << "↩️  撤销: " << getName() << std::endl;
        if (wasOn_) {
            light_.on();
            light_.setBrightness(previousBrightness_);
            light_.setColor(previousColor_);
        }
    }
};

class LightDimCommand : public LightCommand {
private:
    int previousBrightness_;
    
public:
    LightDimCommand(Light& light) : LightCommand(light, "调暗灯光") {}
    
    void execute() override {
        std::cout << "🚀 执行: " << getName() << std::endl;
        previousBrightness_ = light_.getBrightness();
        light_.dim();
    }
    
    void undo() override {
        std::cout << "↩️  撤销: " << getName() << std::endl;
        light_.setBrightness(previousBrightness_);
    }
};

// 具体命令:空调命令
class AirConditionerCommand : public Command {
protected:
    AirConditioner& ac_;
    std::string name_;
    
public:
    AirConditionerCommand(AirConditioner& ac, const std::string& name) 
        : ac_(ac), name_(name) {}
    
    std::string getName() const override {
        return name_;
    }
    
    std::string getDescription() const override {
        return "控制 " + ac_.getLocation() + " 空调";
    }
};

class AirConditionerOnCommand : public AirConditionerCommand {
private:
    bool wasOn_;
    int previousTemp_;
    int previousFanSpeed_;
    std::string previousMode_;
    
public:
    AirConditionerOnCommand(AirConditioner& ac) 
        : AirConditionerCommand(ac, "打开空调") {}
    
    void execute() override {
        std::cout << "🚀 执行: " << getName() << std::endl;
        wasOn_ = ac_.isOn();
        previousTemp_ = ac_.getTemperature();
        previousFanSpeed_ = ac_.getFanSpeed();
        previousMode_ = ac_.getMode();
        
        ac_.on();
        ac_.setTemperature(24);
        ac_.setFanSpeed(3);
        ac_.setMode("cool");
    }
    
    void undo() override {
        std::cout << "↩️  撤销: " << getName() << std::endl;
        if (!wasOn_) {
            ac_.off();
        } else {
            ac_.setTemperature(previousTemp_);
            ac_.setFanSpeed(previousFanSpeed_);
            ac_.setMode(previousMode_);
        }
    }
};

class SetTemperatureCommand : public AirConditionerCommand {
private:
    int targetTemp_;
    int previousTemp_;
    
public:
    SetTemperatureCommand(AirConditioner& ac, int temp) 
        : AirConditionerCommand(ac, "设置温度"), targetTemp_(temp) {}
    
    void execute() override {
        std::cout << "🚀 执行: " << getName() << " 到 " << targetTemp_ << "°C" << std::endl;
        previousTemp_ = ac_.getTemperature();
        ac_.setTemperature(targetTemp_);
    }
    
    void undo() override {
        std::cout << "↩️  撤销: " << getName() << std::endl;
        ac_.setTemperature(previousTemp_);
    }
};

// 具体命令:宏命令 - 一次执行多个命令
class MacroCommand : public Command {
private:
    std::vector<std::unique_ptr<Command>> commands_;
    std::string name_;
    std::string description_;
    
public:
    MacroCommand(const std::string& name, const std::string& description = "")
        : name_(name), description_(description) {
        std::cout << "📋 创建宏命令: " << name_ << std::endl;
    }
    
    void addCommand(std::unique_ptr<Command> command) {
        commands_.push_back(std::move(command));
    }
    
    void execute() override {
        std::cout << "🚀 执行宏命令: " << name_ << " (" << commands_.size() << " 个子命令)" << std::endl;
        for (auto& cmd : commands_) {
            cmd->execute();
        }
    }
    
    void undo() override {
        std::cout << "↩️  撤销宏命令: " << name_ << std::endl;
        // 按相反顺序撤销
        for (auto it = commands_.rbegin(); it != commands_.rend(); ++it) {
            (*it)->undo();
        }
    }
    
    std::string getName() const override {
        return name_;
    }
    
    std::string getDescription() const override {
        return description_.empty() ? 
               "包含 " + std::to_string(commands_.size()) + " 个操作的宏命令" : 
               description_;
    }
    
    size_t getCommandCount() const {
        return commands_.size();
    }
};

调用者实现

Command创建了遥控器和智能家居控制器:

cpp 复制代码
// 调用者:遥控器
class RemoteControl {
private:
    std::vector<std::unique_ptr<Command>> onCommands_;
    std::vector<std::unique_ptr<Command>> offCommands_;
    std::unique_ptr<Command> undoCommand_;
    CommandHistory& history_;
    
public:
    RemoteControl(CommandHistory& history, int slotCount = 8) 
        : history_(history), undoCommand_(nullptr) {
        // 初始化所有插槽为空命令
        auto noCommand = std::make_unique<NoCommand>();
        for (int i = 0; i < slotCount; i++) {
            onCommands_.push_back(std::make_unique<NoCommand>());
            offCommands_.push_back(std::make_unique<NoCommand>());
        }
        std::cout << "🎮 创建遥控器,包含 " << slotCount << " 个插槽" << std::endl;
    }
    
    void setCommand(int slot, std::unique_ptr<Command> onCommand, 
                   std::unique_ptr<Command> offCommand) {
        if (slot >= 0 && slot < onCommands_.size()) {
            onCommands_[slot] = std::move(onCommand);
            offCommands_[slot] = std::move(offCommand);
            std::cout << "🔧 设置插槽 " << slot << " 命令" << std::endl;
        }
    }
    
    void onButtonPressed(int slot) {
        if (slot >= 0 && slot < onCommands_.size()) {
            auto& command = onCommands_[slot];
            command->execute();
            history_.push(std::unique_ptr<Command>(new CommandWrapper(*command)));
        }
    }
    
    void offButtonPressed(int slot) {
        if (slot >= 0 && slot < offCommands_.size()) {
            auto& command = offCommands_[slot];
            command->execute();
            history_.push(std::unique_ptr<Command>(new CommandWrapper(*command)));
        }
    }
    
    void undoButtonPressed() {
        history_.undo();
    }
    
    void redoButtonPressed() {
        history_.redo();
    }
    
    void showControls() {
        std::cout << "\n🎮 遥控器控制面板:" << std::endl;
        std::cout << "==================" << std::endl;
        for (size_t i = 0; i < onCommands_.size(); i++) {
            std::cout << "插槽 " << i << ": [开] " << onCommands_[i]->getName() 
                      << " | [关] " << offCommands_[i]->getName() << std::endl;
        }
        std::cout << "特殊按钮: [撤销] | [重做]" << std::endl;
    }
    
private:
    // 空命令
    class NoCommand : public Command {
    public:
        void execute() override {
            std::cout << "⏹️  空命令 - 无操作" << std::endl;
        }
        void undo() override {
            std::cout << "⏹️  空命令 - 无操作" << std::endl;
        }
        std::string getName() const override { return "空命令"; }
        std::string getDescription() const override { return "不执行任何操作"; }
    };
    
    // 命令包装器,用于历史记录
    class CommandWrapper : public Command {
    private:
        Command& originalCommand_;
        
    public:
        CommandWrapper(Command& cmd) : originalCommand_(cmd) {}
        
        void execute() override {
            originalCommand_.execute();
        }
        
        void undo() override {
            originalCommand_.undo();
        }
        
        std::string getName() const override {
            return originalCommand_.getName();
        }
        
        std::string getDescription() const override {
            return originalCommand_.getDescription();
        }
    };
};

// 调用者:语音助手
class VoiceAssistant {
private:
    std::map<std::string, std::unique_ptr<Command>> voiceCommands_;
    CommandHistory& history_;
    
public:
    VoiceAssistant(CommandHistory& history) : history_(history) {
        std::cout << "🎤 创建语音助手" << std::endl;
    }
    
    void registerCommand(const std::string& voiceCommand, std::unique_ptr<Command> command) {
        voiceCommands_[voiceCommand] = std::move(command);
        std::cout << "🗣️  注册语音命令: \"" << voiceCommand << "\" -> " 
                  << voiceCommands_[voiceCommand]->getName() << std::endl;
    }
    
    void processVoiceCommand(const std::string& command) {
        auto it = voiceCommands_.find(command);
        if (it != voiceCommands_.end()) {
            std::cout << "🎤 语音识别: \"" << command << "\"" << std::endl;
            it->second->execute();
            // 简化:不记录到历史
        } else {
            std::cout << "❌ 未知语音命令: \"" << command << "\"" << std::endl;
        }
    }
    
    void showVoiceCommands() {
        std::cout << "\n🗣️  可用语音命令:" << std::endl;
        for (const auto& pair : voiceCommands_) {
            std::cout << "  \"" << pair.first << "\" -> " << pair.second->getDescription() << std::endl;
        }
    }
};

UML 武功秘籍图

controls uses manages contains <<interface>> Command +execute() : void +undo() : void +getName() : string +getDescription() : string Light -string location_ -bool isOn_ -int brightness_ -string color_ +on() : void +off() : void +setBrightness(int) : void +setColor(string) : void +getStatus() : string LightOnCommand -Light& light_ -string name_ -int previousBrightness_ -string previousColor_ -bool wasOn_ +execute() : void +undo() : void +getName() : string +getDescription() : string MacroCommand -vector<unique_ptr>Command<> commands_ -string name_ -string description_ +addCommand(unique_ptr<Command>) : void +execute() : void +undo() : void +getName() : string +getDescription() : string RemoteControl -vector<unique_ptr>Command<> onCommands_ -vector<unique_ptr>Command<> offCommands_ -unique_ptr<Command> undoCommand_ -CommandHistory& history_ +setCommand(int, unique_ptr<Command>, unique_ptr<Command>) : void +onButtonPressed(int) : void +offButtonPressed(int) : void +undoButtonPressed() : void +showControls() : void CommandHistory -stack<unique_ptr>Command<> history_ -stack<unique_ptr>Command<> redoStack_ +push(unique_ptr<Command>) : void +undo() : void +redo() : void +clear() : void

实战演练:高级命令系统

Command继续展示更复杂的命令模式应用:

cpp 复制代码
// 命令队列和调度器
class CommandScheduler {
private:
    std::queue<std::unique_ptr<Command>> commandQueue_;
    bool isRunning_;
    std::thread workerThread_;
    std::mutex queueMutex_;
    std::condition_variable condition_;
    CommandHistory& history_;
    
public:
    CommandScheduler(CommandHistory& history) : history_(history), isRunning_(false) {
        std::cout << "⏰ 创建命令调度器" << std::endl;
    }
    
    ~CommandScheduler() {
        stop();
    }
    
    void start() {
        if (isRunning_) return;
        
        isRunning_ = true;
        workerThread_ = std::thread(&CommandScheduler::workerLoop, this);
        std::cout << "▶️  启动命令调度器" << std::endl;
    }
    
    void stop() {
        if (!isRunning_) return;
        
        isRunning_ = false;
        condition_.notify_all();
        if (workerThread_.joinable()) {
            workerThread_.join();
        }
        std::cout << "⏹️  停止命令调度器" << std::endl;
    }
    
    void scheduleCommand(std::unique_ptr<Command> command) {
        std::lock_guard<std::mutex> lock(queueMutex_);
        commandQueue_.push(std::move(command));
        condition_.notify_one();
        std::cout << "📅 调度命令: " << commandQueue_.back()->getName() << std::endl;
    }
    
    void scheduleDelayedCommand(std::unique_ptr<Command> command, 
                               std::chrono::milliseconds delay) {
        std::thread([this, cmd = std::move(command), delay]() mutable {
            std::this_thread::sleep_for(delay);
            scheduleCommand(std::move(cmd));
        }).detach();
    }
    
    size_t getQueueSize() const {
        return commandQueue_.size();
    }
    
    void clearQueue() {
        std::lock_guard<std::mutex> lock(queueMutex_);
        while (!commandQueue_.empty()) {
            commandQueue_.pop();
        }
        std::cout << "🧹 清空命令队列" << std::endl;
    }
    
private:
    void workerLoop() {
        while (isRunning_) {
            std::unique_ptr<Command> command;
            
            {
                std::unique_lock<std::mutex> lock(queueMutex_);
                condition_.wait(lock, [this]() { 
                    return !isRunning_ || !commandQueue_.empty(); 
                });
                
                if (!isRunning_ && commandQueue_.empty()) {
                    break;
                }
                
                if (!commandQueue_.empty()) {
                    command = std::move(commandQueue_.front());
                    commandQueue_.pop();
                }
            }
            
            if (command) {
                std::cout << "🎬 执行调度命令: " << command->getName() << std::endl;
                command->execute();
                history_.push(std::move(command));
            }
        }
    }
};

// 命令日志记录器
class CommandLogger {
private:
    std::vector<std::string> logEntries_;
    std::string logFile_;
    
public:
    CommandLogger(const std::string& logFile = "command_log.txt") 
        : logFile_(logFile) {
        std::cout << "📋 创建命令日志记录器: " << logFile_ << std::endl;
    }
    
    void logCommandExecution(const Command& command, bool executed = true) {
        auto now = std::chrono::system_clock::now();
        auto time = std::chrono::system_clock::to_time_t(now);
        
        std::stringstream ss;
        ss << "[" << std::ctime(&time);
        ss.seekp(-1, std::ios_base::end); // 移除换行符
        ss << "] " << (executed ? "执行" : "撤销") << ": " 
           << command.getName() << " - " << command.getDescription();
        
        std::string logEntry = ss.str();
        logEntries_.push_back(logEntry);
        
        std::cout << "📝 " << logEntry << std::endl;
        
        // 写入文件(简化实现)
        // 在实际应用中,这里会写入文件
    }
    
    void showLog(int count = 10) const {
        int start = std::max(0, static_cast<int>(logEntries_.size()) - count);
        std::cout << "\n📜 最近 " << (logEntries_.size() - start) << " 条命令日志:" << std::endl;
        for (int i = start; i < logEntries_.size(); ++i) {
            std::cout << "  " << logEntries_[i] << std::endl;
        }
    }
    
    void clearLog() {
        logEntries_.clear();
        std::cout << "🧹 清空命令日志" << std::endl;
    }
    
    size_t getLogSize() const {
        return logEntries_.size();
    }
};

// 支持事务的命令
class TransactionalCommand : public Command {
protected:
    CommandLogger& logger_;
    std::string name_;
    std::string description_;
    
public:
    TransactionalCommand(CommandLogger& logger, const std::string& name, 
                        const std::string& description = "")
        : logger_(logger), name_(name), description_(description) {}
    
    void execute() override {
        if (performExecute()) {
            logger_.logCommandExecution(*this, true);
            std::cout << "✅ 事务命令执行成功: " << name_ << std::endl;
        } else {
            std::cout << "❌ 事务命令执行失败: " << name_ << std::endl;
        }
    }
    
    void undo() override {
        if (performUndo()) {
            logger_.logCommandExecution(*this, false);
            std::cout << "✅ 事务命令撤销成功: " << name_ << std::endl;
        } else {
            std::cout << "❌ 事务命令撤销失败: " << name_ << std::endl;
        }
    }
    
    std::string getName() const override {
        return name_;
    }
    
    std::string getDescription() const override {
        return description_;
    }
    
protected:
    virtual bool performExecute() = 0;
    virtual bool performUndo() = 0;
};

// 智能场景管理器
class SmartSceneManager {
private:
    std::map<std::string, std::unique_ptr<MacroCommand>> scenes_;
    CommandHistory& history_;
    CommandLogger& logger_;
    
public:
    SmartSceneManager(CommandHistory& history, CommandLogger& logger)
        : history_(history), logger_(logger) {
        std::cout << "🎭 创建智能场景管理器" << std::endl;
    }
    
    void createScene(const std::string& sceneName, const std::string& description = "") {
        auto scene = std::make_unique<MacroCommand>(sceneName, description);
        scenes_[sceneName] = std::move(scene);
        std::cout << "🎨 创建场景: " << sceneName << std::endl;
    }
    
    void addCommandToScene(const std::string& sceneName, std::unique_ptr<Command> command) {
        auto it = scenes_.find(sceneName);
        if (it != scenes_.end()) {
            it->second->addCommand(std::move(command));
            std::cout << "➕ 添加命令到场景 " << sceneName << std::endl;
        }
    }
    
    void activateScene(const std::string& sceneName) {
        auto it = scenes_.find(sceneName);
        if (it != scenes_.end()) {
            std::cout << "🎭 激活场景: " << sceneName << std::endl;
            it->second->execute();
            history_.push(std::unique_ptr<Command>(new MacroCommandWrapper(*(it->second))));
            logger_.logCommandExecution(*(it->second), true);
        } else {
            std::cout << "❌ 未知场景: " << sceneName << std::endl;
        }
    }
    
    void listScenes() const {
        std::cout << "\n🎭 可用场景 (" << scenes_.size() << " 个):" << std::endl;
        for (const auto& pair : scenes_) {
            std::cout << "  • " << pair.first << " (" 
                      << pair.second->getCommandCount() << " 个命令) - " 
                      << pair.second->getDescription() << std::endl;
        }
    }
    
private:
    class MacroCommandWrapper : public Command {
    private:
        MacroCommand& originalMacro_;
        
    public:
        MacroCommandWrapper(MacroCommand& macro) : originalMacro_(macro) {}
        
        void execute() override {
            originalMacro_.execute();
        }
        
        void undo() override {
            originalMacro_.undo();
        }
        
        std::string getName() const override {
            return originalMacro_.getName();
        }
        
        std::string getDescription() const override {
            return originalMacro_.getDescription();
        }
    };
};

完整测试代码

cpp 复制代码
// 测试命令模式
void testCommandPattern() {
    std::cout << "=== 命令模式测试开始 ===" << std::endl;
    
    // 创建命令历史
    CommandHistory history;
    
    // 创建设备
    Light livingRoomLight("客厅");
    Light bedroomLight("卧室");
    AirConditioner livingRoomAC("客厅");
    Curtain livingRoomCurtain("客厅");
    Stereo livingRoomStereo("客厅");
    
    // 创建命令
    auto livingRoomLightOn = std::make_unique<LightOnCommand>(livingRoomLight);
    auto livingRoomLightOff = std::make_unique<LightOffCommand>(livingRoomLight);
    auto livingRoomLightDim = std::make_unique<LightDimCommand>(livingRoomLight);
    
    auto bedroomLightOn = std::make_unique<LightOnCommand>(bedroomLight);
    auto bedroomLightOff = std::make_unique<LightOffCommand>(bedroomLight);
    
    auto acOn = std::make_unique<AirConditionerOnCommand>(livingRoomAC);
    auto setTemp24 = std::make_unique<SetTemperatureCommand>(livingRoomAC, 24);
    
    auto curtainOpen = std::make_unique<CurtainOpenCommand>(livingRoomCurtain);
    auto curtainClose = std::make_unique<CurtainCloseCommand>(livingRoomCurtain);
    
    // 测试基础命令
    std::cout << "\n--- 基础命令测试 ---" << std::endl;
    livingRoomLightOn->execute();
    history.push(std::move(livingRoomLightOn));
    
    acOn->execute();
    history.push(std::move(acOn));
    
    curtainOpen->execute();
    history.push(std::move(curtainOpen));
    
    // 测试撤销
    std::cout << "\n--- 撤销操作测试 ---" << std::endl;
    history.undo();
    history.undo();
    history.undo();
    
    // 测试重做
    std::cout << "\n--- 重做操作测试 ---" << std::endl;
    history.redo();
    history.redo();
    history.redo();
    
    std::cout << "\n=== 基础命令模式测试结束 ===" << std::endl;
}

// 测试宏命令
void testMacroCommands() {
    std::cout << "\n=== 宏命令测试开始 ===" << std::endl;
    
    CommandHistory history;
    
    // 创建设备
    Light livingRoomLight("客厅");
    Light bedroomLight("卧室");
    AirConditioner livingRoomAC("客厅");
    Curtain livingRoomCurtain("客厅");
    Stereo livingRoomStereo("客厅");
    
    // 创建回家场景宏命令
    auto homeScene = std::make_unique<MacroCommand>("回家场景", "模拟回家时的设备状态");
    homeScene->addCommand(std::make_unique<LightOnCommand>(livingRoomLight));
    homeScene->addCommand(std::make_unique<LightOnCommand>(bedroomLight));
    homeScene->addCommand(std::make_unique<AirConditionerOnCommand>(livingRoomAC));
    homeScene->addCommand(std::make_unique<CurtainOpenCommand>(livingRoomCurtain));
    
    // 创建离家场景宏命令
    auto awayScene = std::make_unique<MacroCommand>("离家场景", "模拟离家时的设备状态");
    awayScene->addCommand(std::make_unique<LightOffCommand>(livingRoomLight));
    awayScene->addCommand(std::make_unique<LightOffCommand>(bedroomLight));
    awayScene->addCommand(std::make_unique<AirConditionerOffCommand>(livingRoomAC));
    awayScene->addCommand(std::make_unique<CurtainCloseCommand>(livingRoomCurtain));
    
    std::cout << "\n--- 测试回家场景 ---" << std::endl;
    homeScene->execute();
    history.push(std::move(homeScene));
    
    std::cout << "\n--- 测试离家场景 ---" << std::endl;
    awayScene->execute();
    history.push(std::move(awayScene));
    
    std::cout << "\n--- 撤销场景 ---" << std::endl;
    history.undo();
    
    std::cout << "\n=== 宏命令测试结束 ===" << std::endl;
}

// 测试遥控器
void testRemoteControl() {
    std::cout << "\n=== 遥控器测试开始 ===" << std::endl;
    
    CommandHistory history;
    RemoteControl remote(history, 4);
    
    // 创建设备
    Light livingRoomLight("客厅");
    AirConditioner livingRoomAC("客厅");
    Curtain livingRoomCurtain("客厅");
    Stereo livingRoomStereo("客厅");
    
    // 设置遥控器命令
    remote.setCommand(0, 
        std::make_unique<LightOnCommand>(livingRoomLight),
        std::make_unique<LightOffCommand>(livingRoomLight));
    
    remote.setCommand(1,
        std::make_unique<AirConditionerOnCommand>(livingRoomAC),
        std::make_unique<AirConditionerOffCommand>(livingRoomAC));
    
    remote.setCommand(2,
        std::make_unique<CurtainOpenCommand>(livingRoomCurtain),
        std::make_unique<CurtainCloseCommand>(livingRoomCurtain));
    
    auto stereoOn = std::make_unique<StereoOnCommand>(livingRoomStereo);
    auto stereoOff = std::make_unique<StereoOffCommand>(livingRoomStereo);
    remote.setCommand(3, std::move(stereoOn), std::move(stereoOff));
    
    // 显示遥控器控制
    remote.showControls();
    
    // 测试遥控器操作
    std::cout << "\n--- 测试遥控器操作 ---" << std::endl;
    remote.onButtonPressed(0); // 打开客厅灯
    remote.onButtonPressed(1); // 打开空调
    remote.onButtonPressed(2); // 打开窗帘
    remote.onButtonPressed(3); // 打开音响
    
    std::cout << "\n--- 测试撤销 ---" << std::endl;
    remote.undoButtonPressed(); // 撤销音响
    remote.undoButtonPressed(); // 撤销窗帘
    
    std::cout << "\n--- 测试重做 ---" << std::endl;
    remote.redoButtonPressed(); // 重做窗帘
    remote.redoButtonPressed(); // 重做音响
    
    std::cout << "\n=== 遥控器测试结束 ===" << std::endl;
}

// 测试高级功能
void testAdvancedFeatures() {
    std::cout << "\n=== 高级功能测试开始 ===" << std::endl;
    
    CommandHistory history;
    CommandLogger logger;
    CommandScheduler scheduler(history);
    SmartSceneManager sceneManager(history, logger);
    
    // 创建设备
    Light livingRoomLight("客厅");
    Light bedroomLight("卧室");
    AirConditioner livingRoomAC("客厅");
    
    // 创建场景
    sceneManager.createScene("早晨场景", "早晨起床时的设备状态");
    sceneManager.addCommandToScene("早晨场景", 
        std::make_unique<LightOnCommand>(livingRoomLight));
    sceneManager.addCommandToScene("早晨场景",
        std::make_unique<SetTemperatureCommand>(livingRoomAC, 22));
    sceneManager.addCommandToScene("早晨场景",
        std::make_unique<CurtainOpenCommand>(livingRoomCurtain));
    
    sceneManager.createScene("夜晚场景", "晚上睡觉时的设备状态");
    sceneManager.addCommandToScene("夜晚场景",
        std::make_unique<LightOffCommand>(livingRoomLight));
    sceneManager.addCommandToScene("夜晚场景",
        std::make_unique<LightOffCommand>(bedroomLight));
    sceneManager.addCommandToScene("夜晚场景",
        std::make_unique<SetTemperatureCommand>(livingRoomAC, 20));
    
    // 列出场景
    sceneManager.listScenes();
    
    // 测试场景
    std::cout << "\n--- 测试早晨场景 ---" << std::endl;
    sceneManager.activateScene("早晨场景");
    
    std::cout << "\n--- 测试夜晚场景 ---" << std::endl;
    sceneManager.activateScene("夜晚场景");
    
    // 测试命令调度
    std::cout << "\n--- 测试命令调度 ---" << std::endl;
    scheduler.start();
    
    scheduler.scheduleCommand(std::make_unique<LightOnCommand>(livingRoomLight));
    scheduler.scheduleDelayedCommand(
        std::make_unique<LightOffCommand>(livingRoomLight), 
        std::chrono::seconds(2));
    
    // 等待调度完成
    std::this_thread::sleep_for(std::chrono::seconds(3));
    
    scheduler.stop();
    
    // 显示日志
    std::cout << "\n--- 命令执行日志 ---" << std::endl;
    logger.showLog();
    
    std::cout << "\n=== 高级功能测试结束 ===" << std::endl;
}

// 实战应用:智能家居控制系统
class SmartHomeSystem {
private:
    CommandHistory history_;
    CommandLogger logger_;
    CommandScheduler scheduler_;
    SmartSceneManager sceneManager_;
    RemoteControl remote_;
    VoiceAssistant voiceAssistant_;
    
    // 设备
    Light livingRoomLight_;
    Light bedroomLight_;
    Light kitchenLight_;
    AirConditioner livingRoomAC_;
    AirConditioner bedroomAC_;
    Curtain livingRoomCurtain_;
    Curtain bedroomCurtain_;
    Stereo livingRoomStereo_;
    
public:
    SmartHomeSystem() 
        : history_(), logger_(), scheduler_(history_), 
          sceneManager_(history_, logger_), remote_(history_, 6),
          voiceAssistant_(history_),
          livingRoomLight_("客厅"), bedroomLight_("卧室"), kitchenLight_("厨房"),
          livingRoomAC_("客厅"), bedroomAC_("卧室"),
          livingRoomCurtain_("客厅"), bedroomCurtain_("卧室"),
          livingRoomStereo_("客厅") {
        
        std::cout << "🏠 创建智能家居系统" << std::endl;
        initializeSystem();
    }
    
    void initializeSystem() {
        // 初始化遥控器
        setupRemoteControl();
        
        // 初始化语音命令
        setupVoiceCommands();
        
        // 初始化场景
        setupScenes();
        
        // 启动调度器
        scheduler_.start();
        
        std::cout << "✅ 智能家居系统初始化完成" << std::endl;
    }
    
    void setupRemoteControl() {
        // 设置遥控器命令
        remote_.setCommand(0,
            std::make_unique<LightOnCommand>(livingRoomLight_),
            std::make_unique<LightOffCommand>(livingRoomLight_));
        
        remote_.setCommand(1,
            std::make_unique<AirConditionerOnCommand>(livingRoomAC_),
            std::make_unique<AirConditionerOffCommand>(livingRoomAC_));
        
        remote_.setCommand(2,
            std::make_unique<CurtainOpenCommand>(livingRoomCurtain_),
            std::make_unique<CurtainCloseCommand>(livingRoomCurtain_));
        
        remote_.setCommand(3,
            std::make_unique<StereoOnCommand>(livingRoomStereo_),
            std::make_unique<StereoOffCommand>(livingRoomStereo_));
        
        // 宏命令插槽
        auto allLightsOn = std::make_unique<MacroCommand>("所有灯光打开");
        allLightsOn->addCommand(std::make_unique<LightOnCommand>(livingRoomLight_));
        allLightsOn->addCommand(std::make_unique<LightOnCommand>(bedroomLight_));
        allLightsOn->addCommand(std::make_unique<LightOnCommand>(kitchenLight_));
        
        auto allLightsOff = std::make_unique<MacroCommand>("所有灯光关闭");
        allLightsOff->addCommand(std::make_unique<LightOffCommand>(livingRoomLight_));
        allLightsOff->addCommand(std::make_unique<LightOffCommand>(bedroomLight_));
        allLightsOff->addCommand(std::make_unique<LightOffCommand>(kitchenLight_));
        
        remote_.setCommand(4, std::move(allLightsOn), std::move(allLightsOff));
        
        std::cout << "🎮 遥控器设置完成" << std::endl;
    }
    
    void setupVoiceCommands() {
        voiceAssistant_.registerCommand("打开客厅灯", 
            std::make_unique<LightOnCommand>(livingRoomLight_));
        voiceAssistant_.registerCommand("关闭客厅灯",
            std::make_unique<LightOffCommand>(livingRoomLight_));
        voiceAssistant_.registerCommand("打开空调",
            std::make_unique<AirConditionerOnCommand>(livingRoomAC_));
        voiceAssistant_.registerCommand("温度调高",
            std::make_unique<AirConditionerTempUpCommand>(livingRoomAC_));
        voiceAssistant_.registerCommand("温度调低",
            std::make_unique<AirConditionerTempDownCommand>(livingRoomAC_));
        
        std::cout.println("🎤 语音命令设置完成");
    }
    
    void setupScenes() {
        // 回家场景
        sceneManager_.createScene("回家", "回家时自动设置的场景");
        sceneManager_.addCommandToScene("回家",
            std::make_unique<LightOnCommand>(livingRoomLight_));
        sceneManager_.addCommandToScene("回家",
            std::make_unique<SetTemperatureCommand>(livingRoomAC_, 24));
        sceneManager_.addCommandToScene("回家",
            std::make_unique<CurtainOpenCommand>(livingRoomCurtain_));
        sceneManager_.addCommandToScene("回家",
            std::make_unique<StereoOnCommand>(livingRoomStereo_));
        
        // 电影场景
        sceneManager_.createScene("电影", "观看电影时的最佳环境");
        sceneManager_.addCommandToScene("电影",
            std::make_unique<LightDimCommand>(livingRoomLight_));
        sceneManager_.addCommandToScene("电影",
            std::make_unique<SetTemperatureCommand>(livingRoomAC_, 22));
        sceneManager_.addCommandToScene("电影",
            std::make_unique<CurtainCloseCommand>(livingRoomCurtain_));
        sceneManager_.addCommandToScene("电影",
            std::make_unique<StereoOnCommand>(livingRoomStereo_));
        
        // 睡眠场景
        sceneManager_.createScene("睡眠", "准备睡觉时的环境");
        sceneManager_.addCommandToScene("睡眠",
            std::make_unique<LightOffCommand>(livingRoomLight_));
        sceneManager_.addCommandToScene("睡眠",
            std::make_unique<LightOffCommand>(bedroomLight_));
        sceneManager_.addCommandToScene("睡眠",
            std::make_unique<SetTemperatureCommand>(livingRoomAC_, 20));
        sceneManager_.addCommandToScene("睡眠",
            std::make_unique<SetTemperatureCommand>(bedroomAC_, 20));
        sceneManager_.addCommandToScene("睡眠",
            std::make_unique<CurtainCloseCommand>(livingRoomCurtain_));
        sceneManager_.addCommandToScene("睡眠",
            std::make_unique<CurtainCloseCommand>(bedroomCurtain_));
        
        std::cout << "🎭 场景设置完成" << std::endl;
    }
    
    void runDemo() {
        std::cout << "\n🎮 运行智能家居演示..." << std::endl;
        std::cout << "====================" << std::endl;
        
        // 显示系统状态
        showSystemStatus();
        
        // 测试遥控器
        std::cout << "\n--- 遥控器测试 ---" << std::endl;
        remote_.showControls();
        remote_.onButtonPressed(0); // 打开客厅灯
        remote_.onButtonPressed(1); // 打开空调
        remote_.onButtonPressed(4); // 所有灯光打开
        
        // 测试语音控制
        std::cout << "\n--- 语音控制测试 ---" << std::endl;
        voiceAssistant_.showVoiceCommands();
        voiceAssistant_.processVoiceCommand("打开客厅灯");
        voiceAssistant_.processVoiceCommand("温度调高");
        
        // 测试场景
        std::cout << "\n--- 场景测试 ---" << std::endl;
        sceneManager_.listScenes();
        sceneManager_.activateScene("电影");
        
        // 测试撤销
        std::cout << "\n--- 撤销操作测试 ---" << std::endl;
        remote_.undoButtonPressed();
        remote_.undoButtonPressed();
        
        // 显示最终状态
        std::cout << "\n--- 最终系统状态 ---" << std::endl;
        showSystemStatus();
        logger_.showLog(5);
        history_.showStatus();
    }
    
    void showSystemStatus() {
        std::cout << "\n📊 智能家居系统状态" << std::endl;
        std::cout << "==================" << std::endl;
        std::cout << livingRoomLight_.getStatus() << std::endl;
        std::cout << bedroomLight_.getStatus() << std::endl;
        std::cout << kitchenLight_.getStatus() << std::endl;
        std::cout << livingRoomAC_.getStatus() << std::endl;
        std::cout << bedroomAC_.getStatus() << std::endl;
        std::cout << livingRoomCurtain_.getStatus() << std::endl;
        std::cout << bedroomCurtain_.getStatus() << std::endl;
        std::cout << livingRoomStereo_.getStatus() << std::endl;
    }
    
    ~SmartHomeSystem() {
        scheduler_.stop();
        std::cout << "🏠 关闭智能家居系统" << std::endl;
    }
};

int main() {
    std::cout << "🌈 设计模式武林大会 - 命令模式演示 🌈" << std::endl;
    std::cout << "=====================================" << std::endl;
    
    // 测试基础命令模式
    testCommandPattern();
    
    // 测试宏命令
    testMacroCommands();
    
    // 测试遥控器
    testRemoteControl();
    
    // 测试高级功能
    testAdvancedFeatures();
    
    // 运行智能家居系统演示
    std::cout << "\n=== 智能家居系统演示 ===" << std::endl;
    SmartHomeSystem smartHome;
    smartHome.runDemo();
    
    std::cout << "\n🎉 命令模式演示全部完成!" << std::endl;
    
    return 0;
}

命令模式的武学心得

适用场景

  • 请求队列:需要将请求排队、记录请求日志、支持可撤销操作时
  • 回调机制:需要在不同时间点指定、排队和执行请求时
  • 菜单系统:需要支持菜单项、按钮等用户界面元素时
  • 事务系统:需要实现事务操作,支持回滚时
  • 宏命令:需要支持批量操作和复杂操作序列时

优点

  • 解耦调用者和接收者:调用者不需要知道接收者的具体实现
  • 支持撤销和重做:可以轻松实现命令的撤销和重做功能
  • 支持命令队列:可以将命令排队执行
  • 支持日志记录:可以记录命令执行历史
  • 支持宏命令:可以组合多个命令形成复杂操作

缺点

  • 类数量增加:每个命令都需要一个具体的命令类
  • 复杂度增加:对于简单操作,可能显得过于复杂
  • 执行开销:命令对象的创建和执行可能带来额外开销

武林高手的点评

Template Method 赞叹道:"Command 兄的请求封装确实精妙!能够如此优雅地支持撤销、重做和命令队列,这在需要操作历史的系统中确实无人能及。"

Memento 也点头称赞:"Command 兄专注于操作命令的封装和执行,而我更关注对象状态的保存和恢复。我们都支持撤销操作,但关注点不同。"

Command 谦虚回应:"诸位过奖了。每个模式都有其适用场景。在需要封装操作请求并支持复杂控制时,我的命令模式确实能发挥重要作用。但在需要保存和恢复对象状态时,Memento 兄的方法更加合适。"

下章预告

在Command展示完他那精妙的命令艺术后,Template Method 老成持重地走出,手持一卷蓝图。

"Command 兄的请求封装确实精妙,但在算法结构固定、部分步骤需要变化的情况下,需要更加模板化的处理方式。" Template Method 沉稳地说道,"下一章,我将展示如何通过模板方法模式定义算法的骨架,将某些步骤延迟到子类中实现!"

架构老人满意地点头:"善!算法的模板化设计确实是代码复用的关键。下一章,就请 Template Method 展示他的模板艺术!"


欲知 Template Method 如何通过模板方法模式实现算法的灵活扩展,且听下回分解!

相关推荐
jh_cao1 天前
(1)SwiftUI 的哲学:声明式 UI vs 命令式 UI
ui·swiftui·命令模式
青草地溪水旁3 天前
第十六章:固本培元,守正出奇——Template Method的模板艺术
命令模式
bkspiderx5 天前
C++设计模式之行为型模式:命令模式(Command)
c++·设计模式·命令模式
charlie1145141916 天前
精读C++20设计模式——行为型设计模式:命令模式
c++·学习·设计模式·程序设计·命令模式·c++20
Xiaok10189 天前
Jupyter Notebook 两种模式:编辑模式 & 命令模式
ide·jupyter·命令模式
PaoloBanchero13 天前
Unity 虚拟仿真实验中设计模式的使用 ——命令模式(Command Pattern)
unity·设计模式·命令模式
phdsky15 天前
【设计模式】命令模式
设计模式·命令模式
青草地溪水旁15 天前
设计模式(C++)详解——命令模式(1)
c++·设计模式·命令模式
青草地溪水旁15 天前
设计模式(C++)详解——命令模式(2)
c++·设计模式·命令模式