命令模式
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
本文讲解命令模式框架,代码使用C++语言描述,代码存在的不足或问题有望各位指出。
(1)命令模式代码框架
#include <iostream>
using namespace std;
class Receiver
{
public:
void Action()
{
cout << "执行请求!"<<endl;
}
};
class Command
{
public:
Command(){}
virtual ~Command(){}
Command(Receiver *receiver)
{
this->receiver = receiver;
}
virtual void Execute()=0;
protected:
Receiver *receiver =nullptr;
};
class ConcreteCommand : public Command
{
public:
ConcreteCommand(Receiver *receiver)
{
this->receiver = receiver;
}
void Execute() override
{
receiver->Action();
}
private:
};
class Invoker
{
public:
void setCommand(Command *command)
{
this->command = command;
}
void ExecuteCommand()
{
command->Execute();
}
private:
Command *command =nullptr;
};
int main()
{
Receiver *r = new Receiver();
Command *c = new ConcreteCommand(r);
Invoker *i = new Invoker();
i->setCommand(c);
i->ExecuteCommand();
return 0;
}
(2)烧烤事例使用命令模式
#include <iostream>
#include <vector>
using namespace std;
class Barbecuer
{
public:
Barbecuer(){}
~Barbecuer(){}
void BakeMutton()
{
cout << "烤羊肉串"<<endl;
}
void BakeChickenWing()
{
cout << "烤鸡翅" <<endl;
}
};
class Command
{
public:
Command(){}
virtual ~Command(){}
Command(Barbecuer *receiver)
{
this->receiver = receiver;
}
virtual void ExcuteCommand() =0;
protected:
Barbecuer *receiver = nullptr;
};
class BakeMuttonCommand : public Command
{
public:
BakeMuttonCommand(){}
~BakeMuttonCommand(){}
BakeMuttonCommand(Barbecuer *receiver)
{
this->receiver = receiver;
}
void ExcuteCommand() override
{
receiver->BakeMutton();
}
protected:
};
class BakeMuttonWingCommand :public Command
{
public:
BakeMuttonWingCommand(){}
~BakeMuttonWingCommand(){}
BakeMuttonWingCommand(Barbecuer *receiver)
{
this->receiver = receiver;
}
void ExcuteCommand() override
{
receiver->BakeChickenWing();
}
};
class Waiter
{
public:
void setOrder(Command *command)
{
if(typeid(*command) == typeid(bwc)) //比较指针类型
{
cout << "服务员:鸡翅没有了,请点别的烧烤。"<< endl;
}
else
{
order.push_back(command);
}
}
void cancelOrder(Command *command)
{
auto it =order.begin();
for(;it!=order.end();it++)
{
if(*it==command)
break;
}
if(it !=order.end())
{
order.erase(it);
}
}
void Notify()
{
for(auto out:order)
{
out->ExcuteCommand();
}
}
private:
vector<Command*>order;
BakeMuttonWingCommand bwc;
};
int main()
{
Barbecuer *boy = new Barbecuer();
Command *bakeMuttonCommand1 = new BakeMuttonCommand(boy);
Command *bakeMuttonCommand2 = new BakeMuttonCommand(boy);
Command *bakeChickenWingCommand1 = new BakeMuttonWingCommand(boy);
Waiter *girl = new Waiter();
girl->setOrder(bakeMuttonCommand1);
girl->setOrder(bakeMuttonCommand2);
girl->setOrder(bakeChickenWingCommand1);
girl->cancelOrder(bakeMuttonCommand1);
girl->Notify();
delete boy;
delete bakeMuttonCommand1;
delete bakeMuttonCommand2;
delete bakeChickenWingCommand1;
delete girl;
return 0;
}
命令模式的作用
1、它能较容易地设计一个命令队列
2、在需要的的情况下,可以较容易的将命令计入日志
3、允许接收请求的一方决定是否要否决请求
4、可以容易地实现对请求的撤销和重做
5、由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开。