命令模式(Command): 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
烧烤程序
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<vector>
#include<string>
#include<ctime>
using namespace std;
class Barbecuer
{
public:
void BakeMutton()
{
cout << "烤羊肉串!" << endl;
}
void BakeChickenWing()
{
cout << "烤鸡翅!" << endl;
}
};
class Command
{
protected:
Barbecuer* receiver;
public:
Command(Barbecuer* receiver_t)
{
receiver = receiver_t;
}
virtual void ExcuteCommand() = 0;
};
class BakeMuttonCommand :public Command
{
public:
BakeMuttonCommand(Barbecuer* receiver)
:Command(receiver)
{ }
void ExcuteCommand()
{
receiver->BakeMutton();
}
};
class BakeChickenWingCommand :public Command
{
public:
BakeChickenWingCommand(Barbecuer* receiver)
:Command(receiver)
{ }
void ExcuteCommand()
{
receiver->BakeChickenWing();
}
};
class Waiter
{
private:
vector<Command*> orders;
public:
void SetOrder(Command* command)
{
if (typeid(*command) == typeid(BakeChickenWingCommand))
{
cout << "服务员:鸡翅没有了,请点别的烧烤。" << endl;
}
else
{
orders.push_back(command);
time_t curtime;
time(&curtime);
cout << "增加订单: " << typeid(*command).name()
<< " 时间:" << ctime(&curtime) << endl;
}
}
void CancelOrder(Command* command)
{
for (auto iter = orders.begin(); iter != orders.end(); iter++)
{
if (*iter == command)
{
orders.erase(iter);
time_t curtime;
time(&curtime);
cout << "取消订单: " << typeid(*command).name()
<< " 时间:" << ctime(&curtime) << endl;
}
}
}
void Notify()
{
for (auto _i : orders)
{
_i->ExcuteCommand();
}
}
};
int main()
{
Barbecuer* boy = new Barbecuer();
Command* bakeMuttonCommand1 = new BakeMuttonCommand(boy);
Command* bakeMuttonCommand2 = new BakeMuttonCommand(boy);
Command* bakeChickenWingCommand1 = new BakeChickenWingCommand(boy);
Waiter* girl = new Waiter();
girl->SetOrder(bakeMuttonCommand1);
girl->SetOrder(bakeMuttonCommand2);
girl->SetOrder(bakeChickenWingCommand1);
girl->Notify();
system("pause");
return 0;
}
命令模式的作用
- 第一,它能较容易的设计一个命令队列。
- 第二,在学要的情况下,可以较容易的将命令记入日志。
- 第三,允许接收请求的一方决定是否要否决请求。
- 第四,可以容易的实现对请求的撤销和重做。
- 第五,由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。
- 第六,命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开。