1、介绍
命令模式是⼀种⾏为型设计模式,其允许将请求封装成⼀个对象(命令对象,包含执⾏操作所需的所有信息),并将命令对象按照⼀定的顺序存储在队列中,然后再逐⼀调用执⾏,这些命令也可以⽀持反向操作,进⾏撤销和重做。
命令模式将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
创建步骤:
(1)定义抽象命令类(Command):创建一个抽象类或者接口,其中包含一个纯虚的执行方法,用于执行具体的命令操作。
(2)创建具体命令类(Concrete Command):继承自抽象命令类,实现具体的命令操作,同时持有一个命令接收者对象。
(3)定义命令接收者类(Receiver):这个类包含实际执行命令操作的方法。
(4)创建调用者类(Invoker):这个类负责存储和执行命令对象,可以包含一个命令队列,用于存储多个命令对象。
优点:
(1)降低系统耦合度:将命令的发送者与接收者解耦,方便系统的扩展和维护。
(2)支持命令的撤销和重做:可以灵活地实现对命令的操作历史记录。
(3)增加系统的灵活性:可以方便地添加新的命令。
缺点:
(1)可能导致系统类的数量增加:需要定义多个命令类和相关的处理类。
2、示例
#include <iostream>
#include <vector>
#include <string>
// 接收者接口
class Receiver {//子类必须重写抽象类中所有的纯虚函数,否则子类也是抽象类
public:
virtual void turnOn(std::string light) = 0;
virtual void setSpeed(int speed) = 0;
};
// 具体接收者
class LightReceiver : public Receiver {
public:
void turnOn(std::string light) override {//只重写抽象类中的turnOn函数,LightReceiver也会变为抽象类
std::cout << "Turning on " << light << std::endl;
}
void setSpeed(int speed) override {
std::cout << "Setting fan speed to " << speed << std::endl;
}
};
// 具体接收者
class Fan : public Receiver {
public:
void turnOn(std::string light) override {
std::cout << "Turning on " << light << std::endl;
}
void setSpeed(int speed) override {
std::cout << "Setting fan speed to " << speed << std::endl;
}
};
// 命令接口
class Command {
public:
virtual void execute() = 0;
};
// 具体命令
class LightCommand : public Command {
public:
LightCommand(LightReceiver*pLight,std::string light) : m_pLight(pLight),light_(light) {}
void execute() override {
std::cout << "Turning on " << light_ << std::endl;
m_pLight->turnOn(light_);
}
private:
std::string light_;
LightReceiver* m_pLight;
};
// 具体命令
class FanCommand : public Command {
public:
FanCommand(Fan* pFan,int speed) : m_pFan(pFan),speed_(speed) {}
void execute() override {
std::cout << "Setting fan speed to " << speed_ << std::endl;
m_pFan->setSpeed(speed_);
}
private:
int speed_;
Fan* m_pFan;
};
// 调用者接口
class Invoker {
public:
virtual void setCommand(Command* command) = 0;
virtual void execute() = 0;
};
// 具体调用者
class LightInvoker : public Invoker {
public:
void setCommand(Command* command) override { m_pCommand = command; }
void execute() override { m_pCommand->execute(); }
private:
Command* m_pCommand;
};
int main() {
LightReceiver light;
LightCommand lightCommand(&light,"kitchen");
LightInvoker lightInvoker;
lightInvoker.setCommand(&lightCommand);
lightInvoker.execute(); // 执行命令,调用接收者的turnOn方法,输出"Turning on kitchen"
return 0;
}
结果:
Turning on kitchen
Turning on kitchen