Command设计模式

来源:互联网 发布:js调用手机图库 编辑:程序博客网 时间:2024/05/17 01:27

Command对象是一个“和其实际执行着分开存储”的组件。其重要目的是降低系统中两个部分(请求者 invoker 和接收者 receiver )之间的依存性。

典型的行为次序:

1 客户端产生一个 ConcreteCommand 对象,并传给它足够信息以备执行某项任务。

2 客户端将 ConcreteCommand 对象中的 Command 接口传给 invoker(请求者),由它保存这个接口。

3 此后,一旦调用者认为执行时机已到,便启动 Command 的 Execute() 虚函数。虚拟调用机制会将这个调用动作发给 ConcreteCommand 对象,由后者处理细节。第一种情况是找到 Receiver 对象(任务执行者),并通过该对象实际进行处理,称此类命令为转发式命令。另一种情况是有 ConcreateCommand 对象全权处理,此时 receiver 不复存在,此类命令称为主动式命令。


class ICommand{public:virtual void Excute() = 0;        virtual ~ICommand() {}};class Receiver{public:void Action(){cout << "Command is executing" << endl;}};class ConcreateCommand: public ICommand{typedef void(Receiver::*PCmdFunc)(/*argments list*/);public:ConcreateCommand(Receiver *pReceiver, PCmdFunc pCmd/*, argments list*/) : pReceiver_(NULL), pCmdFunc_(NULL){pReceiver_ = pReceiver;pCmdFunc_ = pCmd;}public:void Excute(){(pReceiver_->*pCmdFunc_)();}private:PCmdFunc pCmdFunc_;Receiver *pReceiver_;};class ActionCommand: public ICommand{public:void Excute(){// 包含由 Receiver 对象中 Action 函数中的所有行为// ...cout << "Command is excuting" << endl;}};class Invoker{public:Invoker(ICommand *pCommand): pCommand_(NULL){pCommand_ = pCommand;}public:void invoke(){if (pCommand_ != NULL)pCommand_->Excute();}private:ICommand *pCommand_;};int main(){// 第一种情况:Receiver 对象为任务执行者,实际进行处理Receiver receiver;ConcreateCommand cmd(&receiver, &Receiver::Action);// 第二种情况:由 ConcreteCommand 对象全权处理ActionCommand actionCmd;// 各种 ConcreteCommand 对象注册到 Invoker 对象中Invoker invoker(&cmd); Invoker invoker2(&actionCmd);// 在需要的时刻启用 Commandinvoker.invoke();invoker2.invoke();return 0;}

这些反映了 Command 模式的两个特点:

*接口分离。invoker 和 receiver 分离。

*时间分离。 Command 保存了一个整装待发的处理请求,供将来调用。

环境概念也很重要。某执行点的“环境”指的是该执行点可见的一组实体(变量和函数)。当处理动作真正开始进行时,必要的环境必须准备就绪,否则处理动作无法执行开来。ConcreteCommand 对象将必要环境的一部分当做自身转改保存起来,并在执行 Execute() 期间取用其中部分消息。ConcreateCommand 保存的环境越多,其独立性越强。

0 0
原创粉丝点击