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