command模式原理

在现实的情况中,有一个实例能非常贴切的描述了Command模式,这就是皇帝和士兵的关系。皇帝作为调用者,士兵是接收者,试想如果皇帝要下达一个命令给士兵,难道他直接跑到这个士兵的前面向他交代命令的细节,然后,士兵领旨执行吗?对于皇帝来说,这是不可能的,因为对皇帝来说,他只想完成某个任务,而谁去帮他完成是无关重要的,所以皇帝就有一种东西叫做圣旨,他只需要下一道圣旨,那谁领旨就与他无关了。
在Command模式中,皇帝就是Invoker、Command就是圣旨、士兵就是接收者。
下面针对这个模式来说明一下Command模式包括几个关键类,Invoker(调用者)、Command(命令)、Receiver(接受者)我们先看看这个模式是如何协作完成的。调用者和接收者通过Command对象来解耦,Command中有一个Receiver的对象,而Invoker中调用Command对象的统一函数Execute,Execute函数才真正调用Receiver中的函数。看到这里,想一下,为什么Invoker不直接调用Receiver中的函数呢?因为:1、有些情况下,调用者不知道接收者实际是什么(象皇帝不知道谁领旨了),那我们的接收者就有一个变化的可能了。2、有些情况下,接收者的接口很混乱,调用者希望有一个统一的接口让他调用。例如可以实现Execute和UnExecute来实现Undo操作。3、其他的,暂时我也只能想到上述的两个使用Command的原因。其他的应用如果有朋友知道,请告知!
下面我们可以看看模拟皇帝的代码,了解一下Command的代码是怎么组织的:


#include
< stdio.h >
#include
< iostream >
using namespace std;

// 圣旨类(Command类)

class Command... ... {

public:virtual~Command()...{}
//统一的函数接口
virtualvoidExecute()=0;
}
;

// 士兵(圣旨的接收者)

class Receiver ... {

public:Receiver(char*pszName)...{strcpy(szName,pszName);}

voidAction()...{cout<<szName<<"领旨!"<<endl;}
//每个士兵有一个名字
private:charszName[20];
}
;


// 具体的圣旨1——抓贼

class ZhuaZeiCommand: public Command ... {

public:ZhuaZeiCommand(Receiver*r):_recver(r)...{
}


virtualvoidExecute()...{cout<<"谁领抓贼圣旨?"<<endl;_recver->Action();}
private:Receiver*_recver;
}
;


// 具体的圣旨2——送钱 // 哪来什么送钱的圣旨?我晕

class SongQianCommand: public Command ... {
public:SongQianCommand(Receiver*r):_recver(r)....{
}

virtualvoidExecute()...{cout<<"谁领送钱圣旨?"<<endl;_recver->Action();}
private:Receiver*_recver;
}
;


// 皇帝类
class Invoker ... {
public:Invoker(Command*c):_cmd(c)...{}
voidInvoke()...{_cmd->Execute();}
private:Command*_cmd;
}
;


// 这个main函数就是应用,我一般把main函数看作是上帝的剧本
// 不是吗?你想要的一切都可以由你来创造,呵呵

void main() ... {

//有两个士兵
Receiverr1("一雨田");
Receiverr2(
"邓一雷");
//两道圣旨,一道是抓贼的,一道是送钱的
//抓贼的给一雨田
ZhuaZeiCommandzc(&r1);

//送钱的给邓一雷
SongQianCommandsc(&r2);

//有一个皇帝,要下圣旨了
//第一道,下的是抓贼圣旨
InvokerI1(&zc);

//第二道,下的是送钱圣旨
InvokerI2(&sc);
//圣旨的执行
I1.Invoke();
I2.Invoke();
}


你可能感兴趣的:(command)