原理
背景
在日常的编程过程当中,我们时常会遇到需要在底层执行许多方法的情况。在工厂模式中,以面馆为例,介绍了如何通过继承抽象接口,帮助面馆实现原材料上的多样性,以区分不同地域之间的食材内容。而命令模式则针对方法的多样性,实现方法要求和执行之间的解耦。当解决问题的方法总是跟随其他因素随机变化时,命令模式能帮助我们进一步增加代码的可扩展性。
原理
命令模式主要服务对象是产生命令的要求者,以及执行命令的执行者。在两者之间,设置了抽象命令接口,具体的执行者们,通过继承该抽象接口,在特定的函数中执行自己的特有命令。同时,在命令要求者类中,可以通过存储不同的执行者类,来实现不同的方法调用要求,比如撤销上一个方法等,或几个方法组合而成的花式命令。
代码解释
#include <iostream>
enum errornum
{
failure = 0,
success
};
enum state
{
OFF = 0,
ON
};
//连通命令和具体执行的接口
class Command
{
public:
virtual void exec() = 0;
virtual void undo() = 0;
};
//空类,为防止段错误问题
class NoCommand:public Command
{
public:
void exec() override
{
std::cout << "empty......" << std::endl;
}
void undo() override
{
std::cout << "empty......" << std::endl;
}
};
//控制类,主要为了控制多种多样的命令
class Control
{
public:
/**
* @brief 设置特别命令类
* @param const class command & my_command 派生的特别类,用于具体执行
*/
inline int32_t setCommand(class Command* my_command)
{
this->my_command = my_command;
return errornum::success;
}
/**
* @brief 封装好的开始函数,用于执行不同操作
*
* @return ** int32_t
*/
int32_t start()
{
state_flag = state::ON;
my_command->exec();
return errornum::success;
}
/**
* @brief 用于执行停止命令
*
* @return ** int32_t errornum 1标志成功
*/
int32_t stop()
{
state_flag = state::OFF;
my_command->undo();
return errornum::success;
}
int32_t undo_work()
{
switch (state_flag)
{
case state::OFF:
start();
break;
case state::ON:
stop();
break;
default:
break;
}
return errornum::success;
}
void Init()
{
my_command = new NoCommand;
}
private:
class Command* my_command;
int32_t state_flag;
};
//具体命令执行
class ParticularCommand:public Command
{
public:
/**
* @brief 执行函数可在此处实现
*
* @return ** void
*/
void exec() override
{
std::cout << "start ParticularCommand......" << std::endl;
}
/**
* @brief 停止函数的具体实现
*
* @return ** void
*/
void undo() override
{
std::cout << "end ParticularCommand......" << std::endl;
}
};
int main(int argc,char* argv[])
{
Control my_control;
my_control.Init();
ParticularCommand *command_1 = new ParticularCommand;
my_control.setCommand(command_1);
my_control.start();
my_control.stop();
my_control.undo_work();
return 1;
}
应用
工作队列
工作队列,即将要执行的方法存入已有队列,实现方法的轮流调用。在C++中可以理解为回调函数,利用容器等将回调函数存储起来,在需要的时候可以进行调用。将回调函数当作常用一般变量与队列结合即可实现工作队列。重点是接口,队列之需要了解接口和接口实现的函数,并不关心继承该接口的具体工作类是如何多样化实现不同行为的。
记录日志
同工作队列,在执行过程中,使用容器等存储执行顺序中的不同回调函数,保留现场数据。当系统出现死机等
思考
C++中的回调函数很重要