定义:
将一个请求封装成一个对象,从而让你可用不同的请求把客户端进行参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。
命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
Command:声明执行操作的接口;
ConcreteCommand:将一个接收者对象绑定于一个动作,之后,调用接收者相应的操作,以实现Execute来完成相应的命令;
Client:创建一个具体命令对象,但是并没有设定它的接收者;
Invoker:要求该命令执行这个请求;
Receiver:知道如何实施与执行一个请求相关的操作,任何类都可能作为一个接收者。
以上这些对象是按照下面的方式进行协作的:
1.Client创建一个ConcreteCommand命令对象,并指定它的Receiver对象;
2.Invoker对象存储该ConcreteCommand对象;
3.该Invoker通过调用Command对象的Execute操作来提交一个请求。如果这个命令请求是可以撤销的,ConcreteCommand就执行Execute操作之前存储当前状态以用于取消该命令请求;
4.ConcreteCommand对象调用Receiver的一些操作以执行该请求。
1,它能较容易地设计一个命令队列;
2,在需要的情况下,可以较容易地将命令记入日志;
3,允许接收请求的一方决定是否要否决请求。
4,可以容易地实现对请求的撤销和重做;
5,由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。
命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开。
Command模式关键就是将一个请求封装到一个类中(Command),再提供处理对象(Receiver),最后Command命令由Invoker激活。另外,我们可以将请求接收者的处理抽象出来作为参数传给Command对象,实际也就是回调的机制来实现这一点。也就是将处理操作方法地址通过参数传递给Command对象,Command对象在适当的时候再调用该函数。
Command模式将调用操作的对象和知道如何实现该操作的对象解耦,在上面Command的结构图中,Invoker对象根本就不知道具体的是哪个对象在处理Execute操作(当然要知道是Command类别的对象)。
在Command要增加新的处理操作对象很容易,我们可以通过创建新的继承自Command的子类来实现这一点。
Command模式可以和备忘录Memento模式结合起来,支持取消的操作。
#include <iostream>
#include <string>
using namespace std;
//抽象命令类
class Command
{
public:
virtual ~Command(){}
virtual void Execute()=0;
protected:
Command(){}
private:
};
class Receiver
{
public:
Receiver(){}
~Receiver(){}
void Action(){cout << "Receiver::Action" << endl;}
protected:
private:
};
class ConcreteCommand : public Command
{
public:
ConcreteCommand(Receiver* pReceiver)
{
_recv=pReceiver;
}
~ConcreteCommand(){}
virtual void Execute()
{
_recv->Action();
}
protected:
private:
Receiver* _recv;
};
class Invoker
{
public:
Invoker(Command* pCommand):_cmd(pCommand){}
~Invoker(){}
void Invoke()
{
_cmd->Execute();
}
protected:
private:
Command* _cmd;
};
int main()
{
//创建具体命令对象pCmd并设定它的接收者pRev
Receiver* pRev = new Receiver();
Command* pCmd = new ConcreteCommand(pRev);
//请求绑定命令
Invoker* pInv = new Invoker(pCmd);
pInv->Invoke();
return 0;
}