设计模式(c++)笔记之十九(Command模式)

一、描述:


      命令模式,将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。应该是一个比较简单的模式了。

      Command 模式的典型结构图为: 




      Command 模式结构图中,将请求的接收者(处理者)放到 Command 的具体子类ConcreteCommand 中,当请求到来时(Invoker 发出 Invoke 消息激活 Command 对象),ConcreteCommand 将处理请求交给 Receiver 对象进行处理。 


二、实例:


描述:

      今天讲命令模式,这个模式从名字上看就很简单,命令嘛,老大发命令,小兵执行就是了,确实是这个意思,但是更深化了,用模式来描述真是是世界的命令情况。正在看这本书的你,我猜测分为两类:已经工作的和没有工作的,先说没有工作的,那你为啥要看这本书,为了以后工作呗,只要你参见工作,你肯定会待在项目组,那今天我们就以项目组为例子来讲述命令模式。

      我是我们部门的项目经理,就是一个项目的头,在中国做项目,项目经理就是什么都要懂,什么都要管,做好了项目经理能分到一杯羹,做不好都是你项目经理的责任,这个是绝对的,我带过太多的项目,行政命令一压下来,那就一条道,做完做好!我们虽然是一个集团公司,但是我们部门是独立核算的,就是说呀,我们部门不仅仅为我们集团服务,还可以为其他甲方服务,赚取更多的外快,所以俺们的工资才能是中上等。在 2007 年我带领了一个项目,比较小,但是钱可不少,是做什么的呢?为一家旅行社建立一套内部管理系统,管理他的客户、旅游资源、票务以及内部管理,整体上类似一个小型的 ERP 系统,门店比较多,员工也比较多,但是需求比较明确,因为他们之前有一套自己购买的内部管理系统,这次变动部分模块基本上是翻版,而且旅行社有自己的IT 部门,比较好相处,都是技术人员,没有交流鸿沟嘛。

      这个项目的成员分工也是采用了常规的分工方式,分为需求组(Requirement Group,简称 RG)、美工组(Page Group,简称 PG)、代码组(我们内部还有一个比较优雅的名字:逻辑实现组,这里使用大家经常称呼的名称吧,英文缩写叫 Code Group,简称 CG),总共加上我这个项目经理正好十个人,刚开始的时候客户(也就是旅行社,甲方)还是很乐意和我们每个组探讨,比如和需求组讨论需求,和美工讨论页面,和代码组讨论实现,告诉他们修改这里,删除这里,增加这些等等,这是一种比较常见的甲乙方合作模式,甲方深入到乙方的项目开发中,我们把这个模式用类图表示一下: 




      但是问题来了,我们修改可以,但是每次都是叫一个组去,布置个任务,然后出计划,次次都这样,如果让你当甲方也就是客户,你烦不烦?而且这种方式很容易出错误呀,而且还真发生过,客户把美工叫过去了,要删除,可美工说需求是这么写的,然后客户又命令需求组过去,一次次的折腾,客户也烦躁了,于是直接抓住我这个项目经理说:

“我不管你们内部怎么安排,你就给我找个接头人,我告诉他怎么做,删除页面了,增加功能了,你们内部 怎么处理,我就告诉他我要干什么就成了...”我一听,好呀,这也正是我想要的,我项目组的兄弟们也已经受不了了,于是我改变了一下我的处理方式, 看看类图(类图稍微更改下名称):



我的工程目录:


             


注释:

main(),客户 

Invoker,命令接收者,如项目经理 

IGroup,执行者接口 

CRequirementGroup,需要组

CPageGroup,美工组

CCodePage,代码组

ICommand,命令接口

CAddRequirementCommand,执行增加一项需求的命令(Execute函数,将调用CRequirementGroup的多个命令。来组合执行用户发出的命令。)

CDeletePageCommand,执行删除一个页面的命令 


命令接收者:Invoker

Invoker.h

#ifndef __Command__Invoker__
#define __Command__Invoker__

#include <iostream>
#include "ICommand.h"

class CInvoker
{
public:
    CInvoker(void);
    ~CInvoker(void);
    void SetCommand(ICommand *pcommand);
    void Action();
private:
    ICommand *m_pCommand;
};

#endif /* defined(__Command__Invoker__) */

Invoker.cpp

#include "Invoker.h"
CInvoker::CInvoker(void)
{
}
CInvoker::~CInvoker(void)
{
}
void CInvoker::SetCommand( ICommand *pcommand )
{
    this->m_pCommand = pcommand;
}
void CInvoker::Action()
{
    this->m_pCommand->Execute();
}

命令接口:IComman类

ICommand.h

#ifndef Command_ICommand_h
#define Command_ICommand_h
#include "RequirementGroup.h"
#include "PageGroup.h"
#include "CodeGroup.h"

class ICommand {   
public:
    
    ICommand(void)
    {
        m_prg = new CRequirementGroup();
        m_ppg = new CPageGroup();
        m_pcg = new CCodeGroup();
    }
    virtual ~ICommand(void)
    {
        delete m_prg;
        delete m_ppg;
        delete m_pcg;
    }
    virtual void Execute() = 0;
    
protected:
    
    CRequirementGroup *m_prg;
    CPageGroup *m_ppg;
    CCodeGroup *m_pcg;
    
};


#endif


执行增加一项需求的命令:CAddRequirementCommand类

CAddRequirementCommand.h

#ifndef __Command__AddRequirementCommand__
#define __Command__AddRequirementCommand__

#include <iostream>
#include "ICommand.h"
class CAddRequirementCommand :public ICommand
{
public:
    CAddRequirementCommand(void);
    ~CAddRequirementCommand(void);
    void Execute();
};

#endif /* defined(__Command__AddRequirementCommand__) */
AddRequirementCommand.cpp

#include "AddRequirementCommand.h"

CAddRequirementCommand::CAddRequirementCommand(void)
{
}
CAddRequirementCommand::~CAddRequirementCommand(void)
{
}
void CAddRequirementCommand::Execute()
{
    //执行增另一项需求的命令
    this->ICommand::m_prg->Find();
    
    //增加一份需求
    this->ICommand::m_prg->Add();
    
    //给出计划
    this->ICommand::m_prg->Plan();
}

执行删除一个页面的命令 :CDeletePageCommand类

CDeletePageCommand.h

#ifndef __Command__DeletePageCommand__
#define __Command__DeletePageCommand__

#include <iostream>
#include "ICommand.h"

class CDeletePageCommand :
public ICommand
{
public:
    CDeletePageCommand(void);
    ~CDeletePageCommand(void);
    void Execute();
};

#endif /* defined(__Command__DeletePageCommand__) */
DeletePageCommand.cpp

#include "DeletePageCommand.h"

CDeletePageCommand::CDeletePageCommand(void)
{
}
CDeletePageCommand::~CDeletePageCommand(void)
{
}
void CDeletePageCommand::Execute()
{
    //执行增另一项需求的命令
    this->ICommand::m_ppg->Find();
    
    //增加一份需求
    this->ICommand::m_ppg->Delete();
    
    //给出计划
    this->ICommand::m_ppg->Plan();
}

执行者接口:IGroup

IGroup.h

#ifndef Command_IGroup_h
#define Command_IGroup_h
class IGroup
{
public:
    IGroup(void){}
    virtual ~IGroup(void){}
    virtual void Find() = 0;
    virtual void Add() = 0;
    virtual void Delete() = 0;
    virtual void Change() = 0;
    virtual void Plan() = 0;
};

需要组:CRequirementGroup类

CRequirementGroup.h

#ifndef __Command__RequirementGroup__
#define __Command__RequirementGroup__

#include <iostream>
#include "IGroup.h"
class CRequirementGroup:public IGroup
{
public:
    CRequirementGroup(void);
    ~CRequirementGroup(void);
    void Find();
    void Add();
    void Delete();
    void Change();
    void Plan();
};


#endif /* defined(__Command__RequirementGroup__) */
CRequirementGroup.cpp

#include "RequirementGroup.h"
using std::cout;
using std::endl;

CRequirementGroup::CRequirementGroup(void)
{
}
CRequirementGroup::~CRequirementGroup(void)
{
}
void CRequirementGroup::Find()
{
    cout << "找到需求组..." << endl;
}
void CRequirementGroup::Add()
{
    cout << "客户要求增加一项需求..." << endl;
}
void CRequirementGroup::Delete()
{
    cout << "要求删除一项需求..." << endl;
}
void CRequirementGroup::Change()
{
    cout << "客户要求修改一项需求..." << endl;
}
void CRequirementGroup::Plan()
{
    cout << "客户要求需求变更计划..." << endl;
}

美工组:CPageGroup

CPageGroup.h

#ifndef __Command__CPageGroup__
#define __Command__CPageGroup__

#include <iostream>
#include "IGroup.h"

class CPageGroup :public IGroup
{
public:
    CPageGroup(void);
    ~CPageGroup(void);
    void Find();
    void Add();
    void Delete();
    void Change();
    void Plan();
};


#endif /* defined(__Command__CPageGroup__) */
CPageGroup.cpp

#include "PageGroup.h"

using std::cout;
using std::endl;
CPageGroup::CPageGroup(void)
{
}

CPageGroup::~CPageGroup(void)
{
}

void CPageGroup::Find()
{
    cout << "找到美工组..." << endl;
}

void CPageGroup::Add()
{
    cout << "客户要求增加一个页面..." << endl;
}

void CPageGroup::Delete()
{
    cout << "客户要求删除一个页面..." << endl;
}

void CPageGroup::Change()
{
    cout << "客户要求修改一个页面..." << endl;
}

void CPageGroup::Plan()
{
    cout << "客户要求页面变更计划..." << endl;
}

代码组:CCodePage

CCodePage.h

#ifndef __Command__CodeGroup__
#define __Command__CodeGroup__

#include <iostream>
#include "IGroup.h"

class CCodeGroup :public IGroup
{
public:
    CCodeGroup(void);
    ~CCodeGroup(void);
    void Find();
    void Add();
    void Delete();
    void Change();
    void Plan();
};

#endif /* defined(__Command__CodeGroup__) */
CCodePage.cpp

#include "CodeGroup.h"
using std::cout;
using std::endl;

CCodeGroup::CCodeGroup(void)
{
}

CCodeGroup::~CCodeGroup(void)
{
}

void CCodeGroup::Find()
{
    cout << "找到代码组..." << endl;
}

void CCodeGroup::Add()
{
    cout << "客户要求增加一项功能..." << endl;
}

void CCodeGroup::Delete()
{
    cout << "客户要求删除一项功能..." << endl;
}

void CCodeGroup::Change()
{
    cout << "客户要求修改一项功能..." << endl;
}

void CCodeGroup::Plan()
{
    cout << "客户要求代码变更计划..." << endl;
}

客户 :main

main.cpp

#include <iostream>
#include "IGroup.h"
#include "ICommand.h"
#include "RequirementGroup.h"
#include "PageGroup.h"
#include "CodeGroup.h"
#include "AddRequirementCommand.h"
#include "DeletePageCommand.h"
#include "Invoker.h"
using std::cout;
using std::endl;

void DoIt()
{
    cout << "----------客户想增加一个需求----------" << endl;
    IGroup *rg = new CRequirementGroup();
    rg->Find();
    rg->Add();
    rg->Plan();
    delete rg;
    cout << endl;
    
    cout << "----------客户又想修改一个页面----------" << endl;
    IGroup *pg = new CPageGroup();
    pg->Find();
    pg->Add();
    pg->Plan();
    delete pg;
    cout << endl;
    
    cout << "----------客户又想删除一个功能----------" << endl;
    IGroup *cg = new CCodeGroup();
    cg->Find();
    cg->Add();
    cg->Plan();
    delete cg;
    cout << endl;
}

void DoNew()
{
    cout << "----------客户觉得烦了,希望只找一个人,并告诉他要做什么----------" << endl;
    cout << "----------客户要求增加一项需求----------" << endl;
    CInvoker gary;
    ICommand *pcommand = new CAddRequirementCommand();
    gary.SetCommand(pcommand);
    gary.Action();
    delete pcommand;
    cout << endl;
    
    //客户想要改动只需要找CInvoker就可以了。
    cout << "----------客户要求删除一个页面----------" << endl;
    CInvoker ricky;
    ICommand *pcommand2 = new CDeletePageCommand();
    ricky.SetCommand(pcommand2);
    ricky.Action();
    delete pcommand2;
    cout << endl;
}


int main(int argc, const char * argv[])
{
    //客户原来的运行流程
    cout<<"客户原来的运行流程"<<endl;
    DoIt();
    
    //客户觉得麻烦了,每次改动都要找不同的组,谈不同的事
    //客户只想找一个人,告诉他要做什么就可以,不想关心由哪几个组来做和怎么做
    cout<<"********************命令模式********************"<<endl;
    DoNew();
    // insert code here...
    std::cout << "Hello, World!\n";
    return 0;
}

结果如下:




参考文献:《设计模式之禅》,《GoF_23种设计模式解析》

参考博客:  http://www.cnblogs.com/wanggary/archive/2011/04/18/2020230.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

热血枫叶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值