这是大话设计模式中的命令模式的c++版本(略微完善了一下比较功能以及展示删除功能,原版只会提示鸡翅不够不能根据不同的材料提出不同的提示且没有展示删除功能)
/*
* command.cpp
*
* Created on: Oct 16, 2017
* Author: clh01s@163.com
* 命令模式:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;
* 对请求排队或记录请求日志,以及支持可撤销操作。
*/
#include <iostream>
#include <list>
using namespace std;
//店家
class Barbecuer
{
public:
Barbecuer(int chicken,int mutton):_chicken(chicken),_mutton(mutton){}
bool BakeMutton()
{
if(_mutton > 0)
{
cout<<"烤羊肉串。"<<endl;
_mutton--;
}else
{
cout<<"羊肉串不够了请点其他的菜"<<endl;
return false;
}
return true;
}
bool BakeChickenWing()
{
if(_chicken > 0)
{
//判断鸡翅是否还有存货
cout<<"烤鸡翅"<<endl;
_chicken--;
}else
{
cout<<"鸡翅不够了请点其他的菜"<<endl;
return false;
}
return true;
}
private:
int _chicken,_mutton;
};
//虚基类
class Command
{
public:
Command(Barbecuer* receiver){receiver_ = receiver;}
virtual ~Command(){}
//命令执行
virtual bool ExcuteCommand()=0;
protected:
Barbecuer* receiver_;
};
//烤羊肉串命令
class BakeMuttonCommand:public Command
{
public:
BakeMuttonCommand(Barbecuer* receiver):Command(receiver){}
//实现执行函数
bool ExcuteCommand() override
{
return Command::receiver_->BakeMutton();
}
};
//烤鸡翅命令
class BakeChikenWingCommand:public Command
{
public:
BakeChikenWingCommand(Barbecuer* receiver):Command(receiver){}
//实现执行函数
bool ExcuteCommand() override
{
return Command::receiver_->BakeChickenWing();
}
};
//服务员类
class Waiter
{
public:
//设置订单
void SetOrder(Command* command)
{
_orders.push_back(command);
}
//删除订单
bool RemoveOrder(Command* command)
{
for(list<Command*>::iterator iter = _orders.begin();iter != _orders.end();++iter)
{
if(*iter == command)
{
cout<<"要删除的订单地址是:"<<command<<" 删除的订单地址是:"<<*iter<<endl;
_orders.erase(iter);
return true;
}
}
return false;
}
//通知执行
void Notify()
{
for(Command* command : _orders)
{
command->ExcuteCommand();
}
//执行完之后删除
_orders.clear();
}
private:
//保存命令
list<Command*> _orders;
};
int main()
{
//初始化店家并且传入羊肉串以及鸡翅数量
Barbecuer* boy = new Barbecuer(2,2);
Waiter girl;
//记录客户要求
girl.SetOrder(new BakeMuttonCommand(boy));
girl.SetOrder(new BakeMuttonCommand(boy));
girl.SetOrder(new BakeChikenWingCommand(boy));
girl.SetOrder(new BakeMuttonCommand(boy));
girl.SetOrder(new BakeChikenWingCommand(boy));
//记录客户要求
//执行
girl.Notify();
//下单后删除
BakeChikenWingCommand* chiken = new BakeChikenWingCommand(boy);
girl.SetOrder(chiken);
girl.RemoveOrder(chiken);
return 0;
}
运行结果:
clh@clh:~/testcode/设计模式$ g++ command.cpp -std=c++11
clh@clh:~/testcode/设计模式$ ./a.out
烤羊肉串。
烤羊肉串。
烤鸡翅
羊肉串不够了请点其他的菜
烤鸡翅
要删除的订单地址是:0x192dd60 删除的订单地址是:0x192dd60
(订单的地址在程序中是以指针的形式保存所以这里输出指针的地址作为比较)
以下内容摘抄自《设计模式》:
命令模式的动机:
命令模式通过将请求本身变成一个对象来使工具箱对象可向未指定的应用对象提出请求。
命令模式适用于以下情况:
1.你需要抽象出待执行的动作以参数化某对象。
2.在不同的时刻指定、排列和执行请求。
3.支持取消操作。command的excute操作可以在实施操作之前将状态存储起来,在取消操作时取消上一次execute调用的效果。
4.支持修改日志,这样当系统崩溃时,这些修改可以被重做一遍。
5.用构建在原语操作上的高层操作构造一个系统。这样一种结构在支持事物的信息系统中很常见。