zoukankan      html  css  js  c++  java
  • 设计模式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派生类的数量增长可能会难以控制。上图是代码实现命令模式时,用到的相关类图。

    学习需要坚持,同时也是痛苦的,谁都想每天下了班,回到家里休息一下,看看电视什么的。但我要坚持下去,我要不停的鼓励自己。并完成自己的学习计划。加油!

  • 相关阅读:
    我是如何学习和工作的(1)
    SQL server事物复制报错:要复制的 LOB 数据的长度(xxxxx)超出了配置的最大值 65536
    SQL Server2012高可用之事物复制(发布订阅)测试
    MySQL参数学习(一)
    Oracle间隔(interval)分区
    oracle异机恢复测试
    使用awrsqrpt.sql查看执行计划demo
    使用10046追踪执行计划demo
    js中call、apply和bind到底有什么区别?
    为什么0.1+0.2=0.30000000000000004
  • 原文地址:https://www.cnblogs.com/liaocheng/p/4361458.html
Copyright © 2011-2022 走看看