命令模式(Command):将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
命令模式的优点:
第一、能较容易的设计一个命令队列。
第二、在需要的情况下,可用较容易地将命令计入日志。
第三、允许接受请求的一方决定是否需要否决请求。
第四、可用容易地实现对请求的撤销和重做。
第五、由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易、
关键优点:把请求一个操作的对象与知道怎么执行一个操作的对象分割开。
如果不清楚一个系统是否需要命令模式,一般就不要着急去实现它,事实上,在需要的时候通过重构实现这个模式并不困难,只有在真正需要如撤销和恢复操作等功能时,把原来的代码重构为命令模式才有意义。
#ifndef COMMAND_H
#define COMMAND_H
#include<iostream>
#include<string>
#include<list>
using namespace std;
class Barbecuer
{
public:
void BakeMutton()
{
cout << "烤羊肉串。\n";
}
void BakeChickenWing()
{
cout << "烤鸡翅。\n";
}
};
class Command
{
protected:
Barbecuer receiver;
public:
Command(){}
Command(Barbecuer & b) :receiver(b){}
virtual void ExcuteCommand() = 0;
};
class BakeMuttonCommand :public Command
{
public:
BakeMuttonCommand(Barbecuer & b) { receiver = b; }
void ExcuteCommand(){ receiver.BakeMutton(); }
};
class BakeChickenWingCommand :public Command
{
public:
BakeChickenWingCommand(Barbecuer & b) { receiver = b; }
void ExcuteCommand(){ receiver.BakeChickenWing(); }
};
class Waiter
{
list<Command *>orders;
public:
void SetOrder(Command * comptr);
void CancelOrder(Command * comptr);
void Notify();
};
void Waiter::SetOrder(Command * comptr)
{
orders.push_back(comptr);
cout << "增加订单\n";
}
void Waiter::CancelOrder(Command * comptr)
{
orders.remove(comptr);
cout << "取消订单\n";
}
void Waiter::Notify()
{
for each (Command * var in orders)
{
var->ExcuteCommand();
}
}
#endif
#include "Command.h"
int main()
{
Barbecuer boy;
BakeChickenWingCommand bakechickenwingcommand1(boy);
BakeChickenWingCommand bakechickenwingcommand2(boy);
BakeMuttonCommand bakemuttoncommand1(boy);
BakeMuttonCommand bakemuttoncommand2(boy);
Waiter girl;
girl.SetOrder(&bakechickenwingcommand1);
girl.SetOrder(&bakechickenwingcommand2);
girl.SetOrder(&bakemuttoncommand1);
girl.SetOrder(&bakemuttoncommand2);
girl.Notify();
girl.CancelOrder(&bakechickenwingcommand2);
girl.Notify();
return 0;
}