【C++设计模式之命令模式:行为型】分析及示例

简介

命令模式是一种行为型设计模式,它将请求封装成一个对象,从而使不同的请求可以被参数化、队列化或记录化。这种模式允许请求的发送者和接收者进行解耦,同时提供更高的灵活性和可扩展性。

描述

命令模式的核心思想是通过命令对象来封装请求。命令对象包含了执行请求的接收者和相应的动作。客户端通过将命令对象传递给调用者来触发请求的执行。

原理

命令模式包含以下几个关键角色:

  • Command(命令):定义了命令的接口,声明了执行命令的方法。
  • ConcreteCommand(具体命令):实现了Command接口,持有接收者对象,并实现具体的命令操作。
  • Receiver(接收者):负责执行具体命令的对象。
  • Invoker(调用者):有命令对象,调用命令来执行请求。

类图

【C++设计模式之命令模式:行为型】分析及示例_第1张图片

其中,Invoker是调用者角色,要求该命令执行这个请求;
Command是命令角色,需要执行的所有命令都在这里声明,可以是接口或抽象类;
Receiver是接收者角色,知道如何实施与执行一个请求相关的操作,任何类都可能作为一个接收者;
ConcreteCommand将一个接收者对象绑定与一个动作,调用接收者相应的操作,以实现Execute。

示例

假设有一个遥控器类 RemoteControl,可以通过按下不同的按钮来执行不同的操作,比如打开电视、关闭电视、调高音量等。我们可以使用命令模式来实现该遥控器:

#include 

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

// Receiver(接收者)
class TV {
public:
    void turnOn() {
        std::cout << "电视已打开" << std::endl;
    }
    
    void turnOff() {
        std::cout << "电视已关闭" << std::endl;
    }
    
    void adjustVolume(int volume) {
        std::cout << "音量已调整为:" << volume << std::endl;
    }
};

// ConcreteCommand(具体命令)
class TurnOnCommand : public Command {
private:
    TV* tv;
public:
    TurnOnCommand(TV* tv) : tv(tv) {}
    
    void execute() {
        tv->turnOn();
    }
};

class TurnOffCommand : public Command {
private:
    TV* tv;
public:
    TurnOffCommand(TV* tv) : tv(tv) {}
    
    void execute() {
        tv->turnOff();
    }
};

class AdjustVolumeCommand : public Command {
private:
    TV* tv;
    int volume;
public:
    AdjustVolumeCommand(TV* tv, int volume) : tv(tv), volume(volume) {}
    
    void execute() {
        tv->adjustVolume(volume);
    }
};

// Invoker(调用者)
class RemoteControl {
private:
    Command* command;
public:
    void setCommand(Command* command) {
        this->command = command;
    }
    
    void pressButton() {
        command->execute();
    }
};

int main() {
    // 创建遥控器和电视对象
    RemoteControl remoteControl;
    TV tv;
    
    // 创建具体命令对象
    Command* turnOnCommand = new TurnOnCommand(&tv);
    Command* turnOffCommand = new TurnOffCommand(&tv);
    Command* adjustVolumeCommand new AdjustVolumeCommand(&tv 10);
    
    // 设置具体命令到遥控器
    remoteControl.setCommand(turnOnCommand);
    remoteControl.pressButton(); // 打开电视
    
    remoteControl.setCommand(adjustVolumeCommand);
    remoteControl.pressButton(); // 调高音量
    
    remoteControl.setCommand(turnOffCommand);
    remoteControl.pressButton(); // 关闭电视
    
    // 释放资源
    delete turnOnCommand;
    delete turnOffCommand;
    delete adjustVolumeCommand;
    
    return 0;
}

输出结果

电视已打开
量已调整为:10
电视已关闭

解释

在上面的示例中,遥控器类 RemoteControl 充当调用者角色,持有命令对象并调用命令的 execute() 方法。具体命令类 TurnOnCommand、TurnOffCommand 和 AdjustVolumeCommand 分别对应打开电视、关闭电视和调整音量这三个具体的命令操作。它们实现了 Command 接口,并在执行 execute() 方法时调用接收者 TV 的相应方法。

结论

命令模式将请求和执行分离开来,提供了一种松耦合的方式,使得请求发送者和接收者可以方便地扩展和变化。同时,命令模式也可以对请求进行队列化、记录化等操作,增加系统的灵活性和可扩展性。

应用场景

  • 需要将具体命令与调用者解耦,使得两者间不直接依赖的情况。
  • 需要对请求进行排队、记录操作历史等场景。
  • 需要支持撤销、重做等功能时。

上述示例实现了一个遥控器控制电视的功能,可以对电视执行打开、关闭和调整音量等操作。通过命令模式,遥控器和具体命令之间实现了解耦,可以很方便地扩展新的命令或修改命令的实现方式。

你可能感兴趣的:(设计模式之C++,c++,Qt记录,c++,设计模式,命令模式)