我与C++设计模式(十八)——命令模式

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:...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值