在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活。
命令模式可以对发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。这就是命令模式的模式动机。
命令模式(Command Pattern):将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。命令模式是一种对象行为型模式,其别名为动作(Action)模式或事务(Transaction)模式。

Command:声明执行操作的接口;
ConcreteCommand:将一个接收者对象绑定于一个动作,之后,调用接收者相应的操作,以实现Execute来完成相应的命令;
Client:创建一个具体命令对象,但是并没有设定它的接收者;
Invoker:要求该命令执行这个请求;
Receiver:知道如何实施与执行一个请求相关的操作,任何类都可能作为一个接收者。
以上这些对象是按照下面的方式进行协作的:
- Client创建一个ConcreteCommand命令对象,并指定它的Receiver对象;
- Invoker对象存储该ConcreteCommand对象;
- 该Invoker通过调用Command对象的Execute操作来提交一个请求。如果这个命令请求是可以撤销的,ConcreteCommand就执行Execute操作之前存储当前状态以用于取消该命令请求;
- ConcreteCommand对象调用Receiver的一些操作以执行该请求。
实现:
#include"stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
// 烤肉师傅
class RoastCook
{
public:
void MakeMutton() { cout << "烤羊肉" << endl; }
void MakeChickenWing() { cout << "烤鸡翅膀" << endl; }
};
// 抽象命令类
class Command
{
public:
Command(RoastCook* temp) { receiver = temp; }
virtual void ExecuteCmd() = 0;
protected:
RoastCook* receiver;
};
// 烤羊肉命令
class MakeMuttonCmd : public Command
{
public:
MakeMuttonCmd(RoastCook* temp) : Command(temp) {}
virtual void ExecuteCmd() { receiver->MakeMutton(); }
};
// 烤鸡翅膀命令
class MakeChickenWingCmd : public Command
{
public:
MakeChickenWingCmd(RoastCook* temp) : Command(temp) {}
virtual void ExecuteCmd() { receiver->MakeChickenWing(); }
};
// 服务员类
class Waiter
{
public:
void SetCmd(Command* temp);
// 通知执行
void Notify();
protected:
vector<Command*> m_commandList;
};
void Waiter::SetCmd(Command* temp)
{
m_commandList.push_back(temp);
cout << "增加订单" << endl;
}
void Waiter::Notify()
{
vector<Command*>::iterator it;
for (it = m_commandList.begin(); it != m_commandList.end(); ++it)
{
(*it)->ExecuteCmd();
}
}
int main()
{
// 店里添加烤肉师傅、菜单、服务员等顾客
RoastCook* cook = new RoastCook();
Command* cmd1 = new MakeMuttonCmd(cook);
Command* cmd2 = new MakeChickenWingCmd(cook);
Waiter* girl = new Waiter();
// 点菜
girl->SetCmd(cmd1);
girl->SetCmd(cmd2);
// 服务员通知
girl->Notify();
return 0;
}
本文介绍命令模式的概念、原理及其应用场景,通过实例演示了如何利用命令模式解耦发送者与接收者,使对象之间的调用关系更加灵活。
1642

被折叠的 条评论
为什么被折叠?



