您的位置:首页 > 其它

命令模式-对象行为模式

2014-03-26 10:52 155 查看
意图:将请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作.

动机:有时必须向某对象提交请求,但并不知道关于被请求的操作或请求的接受者的任何信息。提交一个请求的对象仅需直到如何提交它,而不需要知道该请求将会如何被执行。模式通过将请求本身变成一个对象来使工具箱对象可向未指定的应用对象提出请求。这个对象可被存储并像其他的对象一样被传递。模式的关键是一个抽象的Command类,它定义了一个执行操作的接口,最简单的入execute,具体的command子类将接收者作为其中一个实例变量,用接收者的方法实现execute操作。接收者有指向该请求所需的具体信息。

适用性:

1 抽象出待执行的动作以参数化某对象。

2 在不同的时刻指定,排列和执行请求。

3 支持取消操作。Command的Excute操作可在实施操作前将状态存储起来,在取笑操作时这个状态用来消除该操作的影响。

4 支持修改日志,这样当系统崩溃时,修改可以重做一遍。

5 用构建在原语操作上的高层操作构造一个系统。

结构:



参与者:

Command:声明执行操作的接口。

ConcreteCommand:将一个接收者对象绑定于一个动作;调用接收者相应的操作,以实Excute

Client:创建一个具体命令对象并设定它的接收者。

Invoker:要求该命令执行这个请求。

Receiver:知道如何实施与执行一个请求相关的操作。任何类都可能作为一个接收者。

协作:

Client创建一个ConcreteCommand对象并指定它的Receiver对象

某Invoker对象存储该ConcreteCommand对象

该Invoker通过调用Command对象的Excute操作来提交一个请求。若该命令是可撤销的,ConcreteCommand就在执行Excute操作之前存储当前状态用于取消该命令。

ConcreteCommand对象对调用它的Receiver的一些操作以执行该请求。

下图展示了这些对象的交互,将调用者和接受者解耦:



效果:

1 Command模式将调用操作的对象与知道如何实现该操作的对象解耦。

2 Command是头等对象。它们可像其他的对象一样被操纵和扩展。

3 可将多个命令装配成一个复合命令。一般说来,复合命令是Composite模式的一个实例

4 增加新的Command很容易,因无无需改变已有的类

实现:

1 一个命令对象应达到何种智能程度

2 支持取消和重做,为达到这个目的,ConcreteCommand类可能需要存储额外的状态信息,如

接受者对象,它真正执行处理该请求的各操作。

接收者上执行操作的参数

如果处理请求的操作会改变接收者对象中的某些值,那么这些值也必须保持起来。接收者还必须提供一些操作,以使该命令可将接收者回复到它先前的状态。

3 避免取消操作过程中的错误累积

4 使用C++模板 对不能被取消且不需要参数的命令,可以用C++模板来实现,这样可避免为每一种动作和接收者都创建一个Command子类。

相关模式:

Composite模式可被用来实现宏命令

Memento可悲用来保持某个状态,命令用这一状态来取消它的效果

在被放入历史表列前必须被拷贝的命令起到一种原型的作用。

代码(大话设计模式的例子):

//命令模式

#include <iostream>
#include <string>
#include <list>
#include <algorithm>
#include <ctime>
#include <typeinfo>
using namespace std;

//接受者类
class Barbecuer
{
public:
void BakeMutton()
{
cout << "烤羊肉串!" << endl;
}

void BakeChickenWing()
{
cout << "烤鸡翅" << endl;
}
};

//命令抽象类
class Command
{
public:
Command(Barbecuer& receiver)
{
_receiver = receiver;
}

virtual void ExecuteCommand() = 0;
virtual void CommandType() = 0;
protected:
Barbecuer _receiver;
};

//具体命令
class BakeMuttonCommand : public Command
{
public:
BakeMuttonCommand(Barbecuer& receiver) : Command(receiver)
{
}

void ExecuteCommand()
{
_receiver.BakeMutton();
}

void CommandType()
{
cout << "烤羊肉串命令" << endl;
}
};

class BakeChickenWingCommand : public Command
{
public:
BakeChickenWingCommand(Barbecuer& receiver) : Command(receiver)
{
}

void ExecuteCommand()
{
_receiver.BakeChickenWing();
}

void CommandType()
{
cout << "烤鸡翅命令" << endl;
}
};

//Invoker类
class Waiter
{
public:
//设置订单
void SetOrder(Command& command)
{
if (typeid(command) == typeid(BakeChickenWingCommand))
cout << "服务员:鸡翅没有了,请点别的烧烤" << endl;
else
{
orders.push_back(&command);
cout << "增加订单:";
command.CommandType();
Time();
}
}

//取消订单
void CancelOrder(Command& command)
{
orders.remove(&command);
cout << "取消订单:";
command.CommandType();
Time();
}

//通知全部执行
void Notify()
{
cout << "执行如下命令:" << endl;
for_each(orders.begin(), orders.end(), mem_fun(&Command::ExecuteCommand));
}
private:
void Time()
{
time_t t = time(NULL);
tm* tt = gmtime(&t);
char* ct = asctime(tt);
printf("时间:%s", ct);
}
list<Command*> orders;
};

int main()
{
Barbecuer boy;
BakeMuttonCommand bakeMuttonCommand1(boy);
BakeMuttonCommand bakeMuttonCommand2(boy);
BakeChickenWingCommand bakeChickenWingCommand1(boy);
Waiter girl;

girl.SetOrder(bakeMuttonCommand1);
girl.SetOrder(bakeMuttonCommand2);
girl.SetOrder(bakeChickenWingCommand1);

girl.Notify();

system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: