设计模式C++学习笔记之十二(Command命令模式)
命令模式,将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。应该是一个比较简单的模式了。
12.1.解释
main(),客户
CInvoker,命令接收者,如项目经理
IGroup,执行者接口
CRequirementGroup,实际执行者之一
CPageGroup,实际执行者之二
CCodePage,实际执行者之三
ICommand,命令接口
CAddRequirementCommand,Execute函数,将调用CRequirementGroup的多个命令。来组合执行用户发出的命令。
CDeletePageCommand,同上
... ... 其它命令。
说明:客户只需要知道向Invoker发出命令(多个命令),而不是将命令直接传达给具体的执行者。当然,客户是需要知道都有什么命令的。
注意:客户只发命令,不需要知道由谁来执行和怎么执行,体现出高内聚的特点。用户在发出命令后,是允许撤回的,所以可以增加一个命令“Undo ”,Undo是状态的变更。
看代码:
//Invoker.h
#pragma once
#include "ICommand.h"
class CInvoker
{
public:
    CInvoker(void);
    ~CInvoker(void);
    void SetCommand(ICommand *pcommand);
    void Action();
private:
    ICommand *m_pCommand;
};
//Invoker.cpp
#include "StdAfx.h"
#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();
}
//IGroup.h
#pragma once
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;
};
//RequirementGroup.h
#pragma once
#include "igroup.h"
class CRequirementGroup :
    public IGroup
{
public:
    CRequirementGroup(void);
    ~CRequirementGroup(void);
    void Find();
    void Add();
    void Delete();
    void Change();
    void Plan();
};
//RequirementGroup.cpp
#include "StdAfx.h"
#include "RequirementGroup.h"
#include <iostream>
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;
}
//PageGroup.h
#pragma once
#include "igroup.h"
class CPageGroup :
    public IGroup
{
public:
    CPageGroup(void);
    ~CPageGroup(void);
    void Find();
    void Add();
    void Delete();
    void Change();
    void Plan();
};
//PageGroup.cpp
#include "StdAfx.h"
#include "PageGroup.h"
#include <iostream>
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;
}
//CodeGroup.h
#pragma once
#include "igroup.h"
class CCodeGroup :
    public IGroup
{
public:
    CCodeGroup(void);
    ~CCodeGroup(void);
    void Find();
    void Add();
    void Delete();
    void Change();
    void Plan();
};
//CodeGroup.cpp
#include "StdAfx.h"
#include "CodeGroup.h"
#include <iostream>
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;
}
//ICommand.h
#pragma once
#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;
};
//AddRequirementCommand.h
#pragma once
#include "icommand.h"
class CAddRequirementCommand :
    public ICommand
{
public:
    CAddRequirementCommand(void);
    ~CAddRequirementCommand(void);
    void Execute();
};
//AddRequirementCommand.cpp
#include "StdAfx.h"
#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();
}
//DeletePageCommand.h
#pragma once
#include "icommand.h"
class CDeletePageCommand :
    public ICommand
{
public:
    CDeletePageCommand(void);
    ~CDeletePageCommand(void);
    void Execute();
};
//DeletePageCommand.cpp
#include "StdAfx.h"
#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();
}
//Command.cpp
#include "stdafx.h"
#include "IGroup.h"
#include "CodeGroup.h"
#include "PageGroup.h"
#include "RequirementGroup.h"
#include "Invoker.h"
#include "AddRequirementCommand.h"
#include "DeletePageCommand.h"
#include <iostream>
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 _tmain(int argc, _TCHAR* argv[])
{
    //客户原来的运行流程
    DoIt();
//客户觉得麻烦了,每次改动都要找不同的组,谈不同的事
    //客户只想找一个人,告诉他要做什么就可以,不想关心由哪几个组来做和怎么做
    DoNew();
_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF);
    _CrtDumpMemoryLeaks();
    return 0;
}
记得曾经给系统中增加Timesheet的小功能,在这里面就用到了命令模式,当时也只是练练手,因为命令模式只适用于变化不是很多的场合,因为一个命令就定义为一个ICommand实现类,这样的话,对ICommand派生类的数量增长可能会难以控制。上图是代码实现命令模式时,用到的相关类图。
学习需要坚持,同时也是痛苦的,谁都想每天下了班,回到家里休息一下,看看电视什么的。但我要坚持下去,我要不停的鼓励自己。并完成自己的学习计划。加油!
设计模式C++学习笔记之十二(Command命令模式)的更多相关文章
- 设计模式学习笔记(十五)命令模式及在Spring JdbcTemplate 中的实现
		
命令(Command)模式是指将请求封装成为一个对象,使发出请求和执行请求的责任分割开,方便将命令对象进行存储.传递.调用.增加与管理. 也就是将发送者.接收者和调用命令封装成独立的对象,来供客户端调 ...
 - 设计模式C++学习笔记之十(Builder建造者模式)
		
建造者模式,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.一段晦涩难懂的文字,实现创建不同表示的方法就是给创建的过程传入创建的参数.详细的还是看代码吧. 10.1.解释 ...
 - VSTO 学习笔记(十二)自定义公式与Ribbon
		
原文:VSTO 学习笔记(十二)自定义公式与Ribbon 这几天工作中在开发一个Excel插件,包含自定义公式,根据条件从数据库中查询结果.这次我们来做一个简单的测试,达到类似的目的. 即在Excel ...
 - 汇编入门学习笔记 (十二)——  int指令、port
		
疯狂的暑假学习之 汇编入门学习笔记 (十二)-- int指令.port 參考: <汇编语言> 王爽 第13.14章 一.int指令 1. int指令引发的中断 int n指令,相当于引 ...
 - Binder学习笔记(十二)—— binder_transaction(...)都干了什么?
		
binder_open(...)都干了什么? 在回答binder_transaction(...)之前,还有一些基础设施要去探究,比如binder_open(...),binder_mmap(...) ...
 - MySQL数据库学习笔记(十二)----开源工具DbUtils的使用(数据库的增删改查)
		
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
 - java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域)  (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)
		
java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...
 - Android学习笔记(十二)——实战:制作一个聊天界面
		
//此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! 运用简单的布局知识,我们可以来尝试制作一个聊天界面. 一.制作 Nine-Patch 图片 : Nine-Pa ...
 - Dynamic CRM 2013学习笔记(十二)实现子表合计(汇总,求和)功能的通用插件
		
上一篇 Dynamic CRM 2013学习笔记(十一)利用Javascript实现子表合计(汇总,求和)功能 , 介绍了如何用js来实现子表合计功能,这种方法要求在各个表单上添加js方法,如果有很多 ...
 
随机推荐
- Linux记录-定时crontab
			
/etc/crontab文件和crontab -e命令区别 1.格式不同 分 时 日 月 星期 要运行的命令 第1列分钟1-59 第2列小时1-23(0表示子夜) 第3列日1-31 第4列月1-12 ...
 - Linux记录-I/O系统监控
			
几个基本的概念 在研究磁盘性能之前我们必须先了解磁盘的结构,以及工作原理.不过在这里就不再重复说明了,关系硬盘结构和工作原理的信息可以参考维基百科上面的相关词条——Hard disk drive(英文 ...
 - Linux记录-在线扩容8e
			
1.fdisk -l 2.增加分区 3.3:键入 p,主分区,并键入3(编号): 默认起始扇区和结束扇区即可(键入两次Enter) 键入t,修改分区类型为8e: 键入w,写分区表,然后重启: 卷扩容, ...
 - wordcloud制作logo
			
准备工作: 1.txt文本(ASCII) 2.参照图(色差大或自行调整扫描参数) 3.pycharm安装wordcloud 源码: from os import path from PIL impor ...
 - 解决pycharm启动慢
			
xms -xmx相关参数设置 打开pycharm的安装目录 D:\PyCharm\PyCharm 2018.2.3\bin下文件pycharm.exe.vmoptions修改默认(版本2016.2)的 ...
 - linux_添加图标
			
sudo gedit /usr/share/applications/Pycharm.desktop [Desktop Entry] Type=Application Name=Pycharm Gen ...
 - silverlight用Encoding.UTF8读取shape文件的中文属性值 出现乱码
			
最近用Silverlight读取shape文件,读出的属性居然是乱码. 原因是:Silverlight不支持GB2312. 解决方案: 下载该地址的代码http://encoding4silverli ...
 - getservbyname和getservbyport
			
一.getservbyname函数原型 #include <netdb.h> struct servent *getservbyname(const char *servname, con ...
 - 电脑丢失api-ms-win-core-libraryloader-|1-1-1.dll怎么办
			
电脑从win7升级到win10,到98%的时候提示说丢失.dll,如图,我是64位系统,怎么解决这个问题呢?在脚本之家下载了 放到system32中也没有用,在线等,谢谢! 用C:\Windows\S ...
 - 第20月第4天 pycharm utf-8
			
1.运行python %run a.py 运行 https://blog.csdn.net/little_bobo/article/details/78982412 2.UnicodeDecodeEr ...