中华语言博大精深,该模式之所以被命名为命令模式,自然就是由“命令”这个词抽象来的。
所以,在学习命令模式之前,请先想一下,什么是命令?
单纯以我而言,作为一名任劳任怨的程序仔,谈到命令,我脑海中浮现的第一画面就是我的上司淡定从容的交给我任务,并坚定的告诉我要努力完成的画面。
那么,上述这个画面,如果用命令模式来抽象一下,该怎么描述呢?
&&首先:领导(Leader/Boss)是一个类,他是命令的请求者(发布者——怎么说都一样,反之任务不是他做~呜呜呜)
&&其次:我(Employee/MySelf)是一个类,我是命令的接收者(实现者——就是老黄牛,任劳任怨的不停工作)
&&然后,命令(Command)是一个类,毕竟完成任务才是目的。但仔细想想,你是完成一个命令(任务)就解放了吗?当然不是,你完成一个,后面立马会有N(>=+∞)个任务等着你做。所以,一个类显然是不够的,我们实际需要N个类。这在C++中怎么表示呢?非常简单:一个抽象的命令基类,然后后面跟着它的无数的实际的命令子类。
&&最后,其实就是客户(God—上帝)啦,他向我们提的需求,最后我们的工作成果也需要经过他的验收。命令起于他,终于他。——不过,God属于客户端的事情,姑且算是前端吧,而我们今天只讲述后端的实现,所以介绍他纯属打酱油,凑字数。
那么,分析完后,现在开始贴命令模式的代码了。贴之前,先总结一下上面的几个类:
命令的请求者/发布者——Boss/Leader
命令的接收者/执行者——Employee/MySelf
命令的基类——Command
充满你的生活的无数的子命令——SubCommand:public Command
¥客户——God
【!!!请注意,实际生活中,领导可能有多个,员工也不止你一个,命令或许会很多,实际的任务可能需要大家来共同协作,所以上述的老板,员工(Employee/MySelf)等都可以进行扩展,而并非是一对一。但由于时间是世界上最宝贵的东西,在这里,请原谅我不再进行扩展了,而是简简单单的举个小栗子。毕竟,你爱的是它的灵魂,不是吗?——微笑🙂】
#include<iostream>
#include<vector>
//注:这个类本来应该派生的,简略的写了,意思意思,大家都明白
class Employee
{
public:
void makeTieGuo()
{
std::cout << "打造一口铁锅" << std::endl;
}
void makeDaPao()
{
std::cout << "打造一门红衣大炮" << std::endl;
}
void makeShip()
{
std::cout << "打造一艘航空母舰" << std::endl;
}
};
//注:命令里面需要封装执行者,和执行任务这个接口——因为术业有专攻,你的命令必须由专门的人通过特定的动作完成,
//比如你想打造一口铁锅,你交给一个卖棉花糖的,你觉得他能给你搞定吗?
class Command
{
public:
Command(Employee * myself) :employee(myself)
{
}
virtual void excuteCommand() = 0;
protected:
Employee *employee;
};
//注:Command的子类1
class Sub1Command : public Command
{
public:
Sub1Command(Employee * myself):Command(myself)
{
}
void excuteCommand()
{
employee->makeTieGuo();
}
};
//注:Command的子类2
class Sub2Command : public Command
{
public:
Sub2Command(Employee * myself) :Command(myself)
{
}
void excuteCommand()
{
employee->makeDaPao();
}
};
//注:Command的子类3
class Sub3Command : public Command
{
public:
Sub3Command(Employee * myself) :Command(myself)
{
}
void excuteCommand()
{
employee->makeShip();
}
};
//注:老板类,他应该根据客户需求,有整理任务(添加或者删除任务),并调用员工执行命令的能力
class Boss
{
public:
void addTask(Command * newTask)
{
yourWork.push_back(newTask);
}
void removeTask(Command * oldTask)
{
auto it = find(yourWork.begin(), yourWork.end(), oldTask);
if (it != yourWork.end())
yourWork.erase(it);
}
void NuLiGongZuo()
{
for (std::vector<Command*>::iterator it = yourWork.begin();it != yourWork.end();it++)
{
(*it)->excuteCommand();
}
}
~Boss() //注意,需要加个释放内存的析构,因为后面存放的变量是我new出来的,你说气不气人
{
for (std::vector<Command*>::iterator it = yourWork.begin();it != yourWork.end();it++)
{
delete (*it);
}
}
private:
std::vector<Command *> yourWork;
};
void main()
{
Employee *mySelf = new Employee(); //我去面试一家公司
Boss *Leader = new Boss(); //我见到了领导,他来面试我
Command * task1 = new Sub1Command(mySelf); //领导问我会什么,我说我会打铁锅
Command * task2 = new Sub2Command(mySelf); //领导不太满意,问我还会什么,我说我会造红衣大炮
Command * task3 = new Sub3Command(mySelf); //领导说造红衣大炮过时了,问我还会什么,我说我会造航空母舰——领导很高兴,我入职了
Leader->addTask(task1);//领导接了个打铁锅的活
Leader->NuLiGongZuo();//领导把工作交给我,让我努力工作,说我很有前途,我很激动
delete Leader;//卖铁锅不赚钱,公司宣布破产了
delete mySelf;//我失业了
system("pause");
}