設計模式C++學習筆記之十二(Command命令模式)

來源:互聯網
上載者:User

命令模式,將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支援可撤消的操作。應該是一個比較簡單的模式了。

 

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衍生類別的數量增長可能會難以控制。是代碼實現命令模式時,用到的相關類圖。

學習需要堅持,同時也是痛苦的,誰都想每天下了班,回到家裡休息一下,看看電視什麼的。但我要堅持下去,我要不停的鼓勵自己。並完成自己的學習計劃。加油!

 


概念:將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支援可撤消的操作。

main(),客戶

CInvoker,命令接收者,如專案經理

IGroup,執行者介面

CRequirementGroup,實際執行者之一

CPageGroup,實際執行者之二

CCodePage,實際執行者之三

ICommand,命令介面

CAddRequirementCommand,Execute函數,將調用CRequirementGroup的多個命令。來組合執行使用者發出的命令。

CDeletePageCommand,同上

 

說明:客戶只需要知道向Invoker發出命令(多個命令),而不是將命令直接傳達給具體的執行者。當然,客戶是需要知道都有什麼命令的。

 

注意:客戶只發命令,不需要知道由誰來執行和怎麼執行,體現出高內聚的特點。使用者在發出命令後,是允許撤回的,所以可以增加一個命令“Undo ”,Undo是狀態的變更。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.