1 command 模式的真正作用就是将行为请求者与行为实现者分离开,
下图是 命令的模式的类图:
现在我们将这个图实例化成客户进放点点餐。
Clinent: 相当于客户
Invoker :相当于服务员,服务员接受客户所有的点菜指令,即command ,
ConcreterCommand : 相当于具体的指令,比如是点米饭,还是 点面条,要绑定接受者。
Receiver :相当于厨师,实现所有的命令。
整体来说就是: 客户点餐,通过服务员接受点餐的命令,服务员再把具体的命令传递给厨师,这样子就避免了客户和厨师的直接接触,降低了代码的耦合性,提高了复用性。
总结一点就是行为请求者和行为实现者是分离的。
下面是具体代码实例:
#pragma once
#include<iostream>
using namespace std;
#include<list>
/*
此程序实例是客户到饭店点餐的过程,客户点餐不需要直接告诉厨师,而是告诉服务员,这样子客户和厨师就实现了解耦。
也就是说command的这种设计模式是将将“行为请求者”与“行为实现者”解耦,提高代码的复用性
*/
class Receiver //相当于厨师
{
public:
Receiver()
{
}
~ Receiver()
{
}
void ActionRice() //厨师会两种技术,一种是做米饭,
{
cout<<"Recevier::Action Rice"<<endl;
}
void ActionNoodle() // 另外一种技术是做面条
{
cout<<"Recevier::Action Noodle"<<endl;
}
private:
};
class Command
{
public:
virtual ~Command() //基类的析构函数如果不加virtual ,那么用基类对象用子类创建实例,删除对象的时候,只能执行基类的析构函数,无法执行子类的析构函数。
{
}
virtual void Execute() =0;
protected:
Command()
{
}
};
class ConcreteCommandA:public Command //这是做米饭的命令,任何客户需要点米饭都用这个
{
public:
ConcreteCommandA(Receiver *precevier)
{
m_Recevier = precevier;
}
~ ConcreteCommandA()
{
}
virtual void Execute() //这里就算是不用virtual 也是虚函数,因为基类这个函数是虚函数。
{
m_Recevier->ActionRice();
}
private:
Receiver *m_Recevier;
};
class ConcreteCommandB:public Command //这是做面条的命令,任何客户需要点面条都用这个
{
public:
ConcreteCommandB(Receiver *precevier)
{
m_Recevier = precevier;
}
~ ConcreteCommandB()
{
}
virtual void Execute() //这里就算是不用virtual 也是虚函数,因为基类这个函数是虚函数。
{
m_Recevier->ActionNoodle();
}
private:
Receiver *m_Recevier;
};
class Invoker //这个相当于服务员。 服务员把所有的指令存储,然后去调用这不同的指令。
{
public:
Invoker()
{
}
~ Invoker()
{
}
void AddCmd(Command * pCmd)
{
m_listCmd.push_back(pCmd);
}
void DelCmd(Command * pCmd)
{
cout<<"Del Cmd"<<endl;
list<Command *>::iterator it_B = m_listCmd.begin();
list<Command *>::iterator it_E = m_listCmd.end();
while (it_B != it_E)
{
if((*it_B) == pCmd)
{
delete *it_B;
m_listCmd.erase(it_B);
break;
}
it_B ++;
}
}
void onSendCmd()
{
list<Command *>::iterator it_B = m_listCmd.begin();
list<Command *>::iterator it_E = m_listCmd.end();
while (it_B != it_E)
{
(*it_B)->Execute();
it_B ++;
}
}
private:
list<Command *> m_listCmd;
};
//下面是client点餐过程,
// Command.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "CommandMode.hpp"
int _tmain(int argc, _TCHAR* argv[])
{
Receiver *pRecv= new Receiver(); //创建接收者
Command *pCmdRice = new ConcreteCommandA(pRecv);//创建具体命令并绑定接收者,将做米饭的指令传给厨师
Command *pCmdRNoodle= new ConcreteCommandB(pRecv); //创建具体命令并绑定接收者,将做面条的指令传给厨师
Command *pCmdRice2 = new ConcreteCommandA(pRecv);//创建具体命令并绑定接收者,将做米饭的指令传给厨师
Command *pCmdRNoodle2= new ConcreteCommandB(pRecv); //创建具体命令并绑定接收者,将做面条的指令传给厨师
Invoker *pInv = new Invoker();
pInv->AddCmd(pCmdRice);
pInv->AddCmd(pCmdRice2);
pInv->AddCmd(pCmdRNoodle);
pInv->AddCmd(pCmdRNoodle2);
//pInv->onInvoke();
pInv->onSendCmd();
pInv->DelCmd(pCmdRice);
pInv->DelCmd(pCmdRice2);
pInv->onSendCmd();
system("pause:");
return 0;
}