命令模式
,将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
Command类,用来声明执行操作的接口。
ConcreteCommand类,将一个接受者对象绑定于一个动作,调用接受者相应的操作,以实现Execute。
Invoker类,要求该命令执行这个请求。
Receiver类,知道如何实施与执行一个与请求相关的操作,任何类都可能作为一个接受者。
命令模式的优点:
- 能比较容易的设计一个命令队列
- 在需要的情况下,可以叫容易的将命令计入日志
- 允许接受请求的一方决定是否要否决请求
- 可以容易地实现对请求的撤销和重做
- 加进新的具体命令类不影响其他的类,因此增加新的命令类很容易
- 命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开来。
代码实例结构图:
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
class Barbecuer
{
public:
void BakeMutton()
{
cout << "Bake Mutton!" << endl;
}
void BakeChickenWing()
{
cout << "Bake ChickenWing!" << endl;
}
};
class Command
{
public:
virtual ~Command(){}
Command(Barbecuer* barbecuer)
{
m_Barbecuer = barbecuer;
}
virtual void ExcuteCommand() = 0;
protected:
Barbecuer* m_Barbecuer;
};
class BakeMuttonCommand :public Command
{
public:
BakeMuttonCommand(Barbecuer* barbecuer) :
Command(barbecuer)
{}
virtual void ExcuteCommand()
{
m_Barbecuer->BakeMutton();
}
};
class BakeChickenWingCommand :public Command
{
public:
BakeChickenWingCommand(Barbecuer* barbecuer) :
Command(barbecuer)
{}
virtual void ExcuteCommand()
{
m_Barbecuer->BakeChickenWing();
}
};
class Waiter
{
private:
vector<Command*> orders;
public:
void SetOrder(Command* command)
{
if (true) //可以对请求进行拒绝
{
orders.push_back(command);
cout << "日志:add order" <<endl;
}
}
void CancelOrder(Command* command)
{
vector<Command*>::iterator it = find(orders.begin(), orders.end(), command);
orders.erase(it);
}
void Notify()
{
for each (Command* var in orders)
{
var->ExcuteCommand();
}
}
};
// CommandPattern.cpp
// CommandPattern.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "Command.h"
int _tmain(int argc, _TCHAR* argv[])
{
Barbecuer* boy = new Barbecuer();
Command* MuttonCommand = new BakeMuttonCommand(boy);
Command* ChickenCommand = new BakeChickenWingCommand(boy);
Waiter girl;
cout << "点菜吧" << endl;
girl.SetOrder(MuttonCommand);
girl.SetOrder(MuttonCommand);
girl.SetOrder(ChickenCommand);
cout << "做菜吧" << endl;
girl.Notify();
cout << "不要羊肉了" << endl;
girl.CancelOrder(MuttonCommand);
girl.Notify();
getchar();
return 0;
}