目录

行为变化_Command


状态变化模式

在组件的构建过程中,组件行为的变化经常导致组件本身剧烈的变化。“行为变化“模式将组件的行为和组件本身进行解耦,从而支持组件行为的变化,实现两者之间的松耦合。

典型模式

  • Command
  • Visitor

1 Command

1.1 模式动机

在软件构建过程中,“行为请求者”与“行为实现者“通常呈现一种*紧耦合 °。但在某些场合——比如需要对行为进行“记录、撤销/重做 (undo/redo)、事务“等处理,这种无法抵御变化的紧耦合是不合适的。

在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。

1.2 模式定义

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

1.3 模式示例代码

# include <iostream>
# include <vector>

// 抽象命令类:命令
class Command {
public:
    virtual void execute() = 0;
};

// 具体命令类:开机命令
class PowerOnCommand : public Command {
public:
    PowerOnCommand() {}

    void execute() {
        std::cout << "执行开机命令" << std::endl;
        // 执行开机操作的具体逻辑...
    }
};

// 具体命令类:关机命令
class PowerOffCommand : public Command {
public:
    PowerOffCommand() {}

    void execute() {
        std::cout << "执行关机命令" << std::endl;
        // 执行关机操作的具体逻辑...
    }
};

// 具体命令类:调高音量命令
class VolumeUpCommand : public Command {
public:
    VolumeUpCommand() {}

    void execute() {
        std::cout << "执行调高音量命令" << std::endl;
        // 执行调高音量操作的具体逻辑...
    }
};

// 具体命令类:调低音量命令
class VolumeDownCommand : public Command {
public:
    VolumeDownCommand() {}

    void execute() {
        std::cout << "执行调低音量命令" << std::endl;
        // 执行调低音量操作的具体逻辑...
    }
};

// 调用者类:遥控器
class RemoteController {
public:
    void setCommand(Command* command) {
        this->command = command;
    }

    void pressButton() {
        command->execute();
    }

private:
    Command* command;
};

int main() {
    // 创建命令对象
    Command* powerOnCommand = new PowerOnCommand();
    Command* powerOffCommand = new PowerOffCommand();
    Command* volumeUpCommand = new VolumeUpCommand();
    Command* volumeDownCommand = new VolumeDownCommand();

    // 创建遥控器对象
    RemoteController remote;

    // 设置并执行命令
    remote.setCommand(powerOnCommand);
    remote.pressButton();

    remote.setCommand(volumeUpCommand);
    remote.pressButton();

    remote.setCommand(volumeDownCommand);
    remote.pressButton();

    remote.setCommand(powerOffCommand);
    remote.pressButton();

    // 释放内存(可选)
    delete powerOnCommand;
    delete powerOffCommand;
    delete volumeUpCommand;
    delete volumeDownCommand;

    return 0;
}

2 要点总结

Command 模式的根本目的在于将“行为请求者”与“行为实现者”解耦,在面向对象语言中,常见的实现手段是“将行为抽象为对象“。

实现 Command 接口的具体命令对象 Concrete Command 有时候根据需要可能会保存一些额外的状态信息。通过使用 Composite 模式, 可以将多个“命令”封装为一个“复合命令”MacroCommand。

Command 模式与 C++中的函数对象有些类似。但两者定义行为接只的规范有所区到:Command 以面向对象中的接口-实现‘来定义行为接口规范,更严格,但有性能损失;C++函数对象以函数签名来定义行为接口规范,更灵活,性能更高。