命令 模式

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

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

3、原理
命令模式包含以下几个关键角色:

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

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

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

#include <iostream>

// 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 的相应方法。

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

7、应用场景1
需要将具体命令与调用者解耦,使得两者间不直接依赖的情况。
需要对请求进行排队、记录操作历史等场景。
需要支持撤销、重做等功能时。
上述示例实现了一个遥控器控制电视的功能,可以对电视执行打开、关闭和调整音量等操作。通过命令模式,遥控器和具体命令之间实现了解耦,可以很方便地扩展新的命令或修改命令的实现方式。

应用场景2
1.实现宏命令:命令模式可以与组合模式结合,将多个命令装配成一个组合命令,即宏命令。
2.日志记录和事务处理:在命令模式中,可以方便地增加额外功能,比如日志记录。此外,如果一个操作需要由多个子操作构成,而这些子操作需要被打包在一起作为一个单独的事务来执行,命令模式可以帮助实现这一功能。
3.支持撤销和重做:命令模式可以方便地实现撤销(Undo)和重做(Redo)功能。
4.队列请求:当需要将请求排队,例如用户界面中的点击事件或网络请求,命令模式可以将这些请求封装为对象并放入队列中等待处理。
5.多线程操作:命令模式可以帮助多线程操作,多个线程可以发出操作命令,程序可以在后台自动发出指令并处理其他业务,而不用等待线程完成操作。
6.系统需要将请求调用者和请求接收者解耦:命令模式使调用者和接收者不直接交互。
7.系统随机请求命令或经常增加、删除命令:命令模式可以方便地实现这些功能。
8.当系统需要执行一组操作时:命令模式可以定义宏命令来实现该功能。

总的来说,命令模式的应用场景主要在于解耦请求与实现,封装接收方具体命令的实现细节,使得请求方的代码架构稳定,具备良好的扩展性。


原文链接:https://blog.51cto.com/u_16417016/8930445

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值