command模式的逻辑讲解也很少,书中描述的是:Command模式通过将请求封装到一个类中,即Command,然后将请求的接受者Receiver存放到具体的实现类ConcreteCommand中,从而实现调用操作的对象和操作的具体实现者之间解耦。上图:
图中的Invoker类是请求到来时,由Invoker发出激活Command对象。其实整个流程就是,Invoker激活Command,让Command去调用它绑定的Receiver完成响应处理,这就是一个连锁机制。
代码:
#ifndef _RECEIVER_H__
#define _RECEIVER_H__
class receiver
{
public:
receiver();
~receiver();
void action();//处理消息
};
#endif
//receiver.cpp
#include "receiver.h"
#include <iostream>
using namespace std;
receiver::receiver()
{
}
receiver::~receiver()
{
}
void receiver::action()
{
cout<<"RECEIVER ACTION:..."<<endl;
}
#ifndef _COMMAND_H__
#define _COMMAND_H__
class receiver;
class command
{
public:
virtual ~command();
virtual void execute() = 0;
protected:
command();
};
class concrete_command_A:public command
{
public:
concrete_command_A(receiver *);
~concrete_command_A();
void execute();
private:
receiver *_p_rev;
};
class concrete_command_B:public command
{
public:
concrete_command_B(receiver *);
~concrete_command_B();
void execute();
private:
receiver *_p_rev;
};
#endif
//command.cpp
#include "receiver.h"
#include "command.h"
#include <iostream>
using namespace std;
command::command()
{
}
command::~command()
{
}
//-----------------A----------------------
concrete_command_A::concrete_command_A(receiver * p_rev)
:_p_rev(p_rev)
{
}
concrete_command_A::~concrete_command_A()
{
if (_p_rev)
{
delete _p_rev;
_p_rev = NULL;
}
}
void concrete_command_A::execute()
{
cout<<"CONCRETE_COMMAND A:"<<endl;
_p_rev->action();
}
//-----------------B----------------------
concrete_command_B::concrete_command_B(receiver * p_rev)
:_p_rev(p_rev)
{
}
concrete_command_B::~concrete_command_B()
{
if (_p_rev)
{
delete _p_rev;
_p_rev = NULL;
}
}
void concrete_command_B::execute()
{
cout<<"CONCRETE_COMMAND B:"<<endl;
_p_rev->action();
}
#ifndef _INVOKER_H__
#define _INVOKER_H__
class command;
class invoker
{
public:
invoker(command *);
~invoker();
void invoke();
private:
command *_p_cmd;
};
#endif
//invoker.cpp
#include "invoker.h"
#include "command.h"
#include <iostream>
using namespace std;
invoker::invoker(command * p_cmd)
:_p_cmd(p_cmd)
{
}
invoker::~invoker()
{
if (_p_cmd)
{
delete _p_cmd;
_p_cmd = NULL;
}
}
void invoker::invoke()
{
_p_cmd->execute();
}
#include "receiver.h"
#include "command.h"
#include "invoker.h"
#include <iostream>
using namespace std;
int main(int argc,char **argv)
{
receiver *p_rev = new receiver();
command *p_cmd_A = new concrete_command_A(p_rev);
invoker *p_ivk = new invoker(p_cmd_A);
p_ivk->invoke();
command *p_cmd_B = new concrete_command_B(p_rev);
delete p_ivk;
p_ivk = new invoker(p_cmd_B);
p_ivk->invoke();
return 0;
}
输出:
$ ./command.exe
CONCRETE_COMMAND A:
RECEIVER ACTION:...
CONCRETE_COMMAND B:
RECEIVER ACTION:...
此外,作者又提出了另一种实现思路——回调,将Receiver的Action函数地址作为参数,传到command中,当然,command中设计了一个对应的函数指针。
代码如下:
#ifndef _SIMPLE_COMMAND_H__
#define _SIMPLE_COMMAND_H__
#include "command.h"
#include "receiver.h"
class simple_command:public command
{
public:
typedef void (receiver::* Action)(); //定义类的非静态函数指针
simple_command(receiver *p_rev,Action p_act)
:_p_rev(p_rev),_p_Act(p_act)
{
}
~simple_command()
{
delete _p_rev;
}
void execute()
{
(_p_rev->*_p_Act)(); //调用到函数指针指向函数
}
private:
receiver *_p_rev;
Action _p_Act;
};
#endif
main.cpp
#include "receiver.h"
#include "simple_command.h"
int main(int argc,char ** argv)
{
receiver *p_rev = new receiver();
command *p_cmd = new simple_command(p_rev,&receiver::action);
p_cmd->execute();
return 0;
}
结果:
$ ./simple_command.exe
RECEIVER ACTION:...