漫谈设计模式之命令模式(Command)

概念

Command模式也叫命令模式,是行为设计模式的一种,Command模式通过被称为Command的类封装了对目标对象的调用行为以及调用参数。

 在面向对象的程序设计中,一个对象调用另一个对象,一般情况下的调用过程是:创建目标对象实例-->设置调用参数-->抵用目标对象的方法。

但在有些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种专门的类称作command类。

整个调用过程比较复杂,或者存在多处这种调用。这时,使用Command类对该调用加以封装,便于功能的再利用。

调用前后需要对调用参数进行某些处理,调用前后需要进行某些额外处理:比如日志,缓存,记录历史操作等。


命令模式结构图


示例代码

#include <iostream>
#include <list>

using namespace std;


class Doctor
{
public:
    void treatEye()
    {
        cout<<"doctor treat eye!"<<endl;
    }

    void treatNouse()
    {
        cout<<"doctor treat nouse!"<<endl;
    }
};

class Command
{
public:
    Command() {}
    virtual ~Command() {}

    virtual void treat() = 0;
};


class CommandTreatEye : public Command
{
public:
    CommandTreatEye(Doctor* doctor)
    {
        m_doctor = doctor;
    }

    void treat()
    {
        m_doctor->treatEye();
    }

private:
    Doctor* m_doctor;

};

class CommandTreatNouse : public Command
{
public:
    CommandTreatNouse(Doctor* doctor)
    {
        m_doctor = doctor;
    }

    void treat()
    {
        m_doctor->treatNouse();
    }

private:
    Doctor* m_doctor;

};

class BeautyNurse
{
public:
    BeautyNurse(Command* command)
    {
        m_command = command;
    }

    void submittedCase() //提交病例(下达命令)
    {
        m_command->treat();
    }

private:
    Command* m_command;
};

//护士长
class HeadNurse
{
public:
    HeadNurse()
    {
        m_list.clear();
    }

    void setCommand(Command* cmd)
    {
        m_list.push_back(cmd);
    }

    void submittedCase() //提交病例(下达命令)
    {
        list<Command*>::iterator it = m_list.begin();

        while( it != m_list.end() )
        {
            (*it)->treat();
            ++it;
        }
    }

private:
    list<Command*> m_list;
};

int main_1()
{

    HeadNurse* pHeadNurse = NULL;
    Doctor* pDoctor = NULL;
    Command* pCommandTreatEye = NULL;
    Command* pCommandTreatNouse = NULL;

    pDoctor = new Doctor();
    pCommandTreatEye = new CommandTreatEye(pDoctor);
    pCommandTreatNouse = new CommandTreatNouse(pDoctor);
    pHeadNurse = new HeadNurse();

    pHeadNurse->setCommand(pCommandTreatEye);
    pHeadNurse->setCommand(pCommandTreatNouse);
    pHeadNurse->submittedCase();


    delete pDoctor;
    delete pCommandTreatEye;
    delete pCommandTreatNouse;
    delete pHeadNurse;

    return 0;
}


int main(int argc, char* argv[])
{
    (void)argc,(void)argv;

    BeautyNurse* pBeautyNurse = NULL;
    Doctor* pDoctor = NULL;
    Command* pCommand = NULL;

    pDoctor = new Doctor();
    //pCommand = new CommandTreatEye(pDoctor);
    pCommand = new CommandTreatNouse(pDoctor);
    pBeautyNurse = new BeautyNurse(pCommand);
    pBeautyNurse->submittedCase();



    delete pDoctor;
    delete pCommand;
    delete pBeautyNurse;

    cout<<"******************"<<endl;
    main_1();

    return 0;
}

运行结果

命令模式优点

  • 类间解耦:调用者角色与接收者角色之间没有任何依赖关系,调用者实现功能时只需调用Command 抽象类的execute方法就可以,不需要了解到底是哪个接收者执行。
  • 可扩展性:Command的子类可以非常容易地扩展,而调用者Invoker和高层次的模块Client不产生严 重的代码耦合。
  • 命令模式结合其他模式会更优秀:命令模式可以结合责任链模式,实现命令族解析任务;结合模板方法模式,则可以减少 Command子类的膨胀问题。


命令模式缺点

命令模式也是有缺点的,请看Command的子类:如果有N个命令,问题就出来 了,Command的子类就可不是几个,而是N个,这个类膨胀得非常大,这个就需要读者在项 目中慎重考虑使用。



  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值