第23章命令模式
一 概念
- 命令模式:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
二 UML图
- Command 用来声明执行操作的接口
- ConcreteCommand 将一个接受者对象绑定于一个动作,调用接收者相应的操作,以实现Exectue
- Invoker类 要求该命令执行这个请求
- Receiver类 知道如何实施与执行一个与请求相关的操作,任何类都可能作为一个接收者
三 命令模式的优点
- 它能较容易地设计一个命令队列
- 在需要的情况下,可以较容易地将命令记入日志
- 允许接收请求的一方决定是否要否决请求
- 可以容易地实现对请求的撤销和重做
- 由于加进新的具体命令类不影响其他类,因此增加新的具体命令类很容易
- 命令模式把请求一个操作的对象与指导怎么执行一个操作的对象分割开
四 C++代码实现
编译器:gcc 7.4.0
// lesson1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <list>
#include <time.h>
using namespace std;
//烤肉串者
class Barbecuer
{
public:
void BakeMutton()
{
cout << "\n烤肉者已经收到命令,开始烤羊肉串!" << endl;
}
void BakeChickenWing()
{
cout << "\n烤肉者已经收到命令,开始烤鸡翅!" << endl;
}
};
//抽象命令类
class Command
{
public:
//抽象命令类,只要确定"烤肉串者"是谁
Command(Barbecuer* receiver)
{
this->m_receiver = receiver;
}
virtual void ExctueCommand() = 0;
protected:
Barbecuer* m_receiver;
};
//具体的命令类
class BakeMuttonCommand : public Command
{
public:
BakeMuttonCommand(Barbecuer* receiver) : Command(receiver)
{
}
void ExctueCommand() override
{
this->m_receiver->BakeMutton();
}
};
class BakeChickenWingCommand : public Command
{
public:
BakeChickenWingCommand(Barbecuer* receiver) : Command(receiver)
{
}
void ExctueCommand() override
{
this->m_receiver->BakeChickenWing();
}
};
//服务员类
class Waiter
{
public:
Waiter()
{
this->order = new list<Command*>;
}
//设置订单
void SetOrder(Command* command)
{
if (typeid(*command) == typeid(BakeChickenWingCommand))
{
//cout << "服务员:鸡翅没有了,请点别的烧烤!" << endl;
time_t now = time(0);
cout << "\n增加订单: " << "命令模式.烤鸡翅" << "时间:" << asctime(gmtime(&now));
this->order->push_back(command);
}
else if (typeid(*command) == typeid(BakeMuttonCommand))
{
time_t now = time(NULL);
cout << "\n增加订单: " << "命令模式.烤肉串" << "时间:" << asctime(gmtime(&now)) << endl;
this->order->push_back(command);
}
}
//取消订单
void CancelOrder(Command* command)
{
for (list<Command*>::iterator it = this->order->begin(); it != this->order->end(); ++it)
{
}
}
//通知执行
void Notify()
{
for (list<Command*>::iterator it = this->order->begin(); it != this->order->end(); ++it)
{
(*it)->ExctueCommand();
}
}
private:
list<Command*>* order; //存放具体命令的容器
};
//客户端
int main()
{
//开店前的准备
Barbecuer* boy = new Barbecuer();
Command* bakeMuttonCommand1 = new BakeMuttonCommand(boy);
Command* bakeMuttonCommand2 = new BakeMuttonCommand(boy);
Command* bakeChickenWingCommand1 = new BakeChickenWingCommand(boy);
Waiter* gril = new Waiter();
//开门营业
gril->SetOrder(bakeChickenWingCommand1);
gril->SetOrder(bakeMuttonCommand2);
gril->SetOrder(bakeChickenWingCommand1);
//点菜完毕,通知厨房
gril->Notify();
return 0;
}