-
命令模式:一種行為型設(shè)計模式
應(yīng)用場景:
在GOF的《設(shè)計模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》一書中對命令模式是這樣說的:將一個請求封裝為一個對象,從而使你可以用不同的請求對客戶進行參數(shù)化鞋邑,將請求排隊或記錄請求日志鸵鸥,以及支持可撤銷的操作艾凯。
這段話的意思我在剛剛了解這個設(shè)計模式時沒有很懂伸头,可以在看完全文后再回來看一遍酪术。
這個設(shè)計模式的應(yīng)用很多阶剑。
即將要開始被天天談?wù)摰?2306訂票網(wǎng)站,每個用戶發(fā)起訂票請求后汤善,該請求不會被立即執(zhí)行什猖,而是會進入消息隊列。同一用戶再次發(fā)起請求時如果前一請求尚在隊列中排隊红淡,新的請求會被忽略不狮,避免了惡意刷票,優(yōu)化了服務(wù)器的性能锉屈。而何時將隊列中的消息取出荤傲,統(tǒng)一處理,將由系統(tǒng)其他設(shè)置決定颈渊。這個隊列就是請求的收集者。
舉例:
我還是以公司里的審批制度舉例终佛。
在部門每月末收集報銷單時俊嗽,一般會指定一個收集者,這個人負責(zé)收集部門內(nèi)所有的報銷單铃彰,收集完成后統(tǒng)一交給審批者進行審批绍豁。
而且,不同種類的報銷單可能由不同的人審批牙捉,都由這個收集者分配竹揍。
這個收集者就是上述的隊列,他可以對報銷單的審批順序進行排列邪铲,也可以對數(shù)目和人員進行記錄芬位,以及支持撤銷報銷的操作。實現(xiàn)方式:
需要創(chuàng)建三個類带到,請求類昧碉,審批人類和收集者類
請求類中要通過成員變量指定審批人,審批人要提供審批接口,收集者類中要有容器用來容納請求被饿,并提供統(tǒng)一處理的方法四康。
以下是命令模式的簡單代碼實現(xiàn)
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
//請求抽象類
class Request
{
public:
Request(int iNo):m_iNo(iNo){}
virtual void Execute() = 0;
int GetID(){return m_iNo;}
protected:
int m_iNo;//請求ID
};
//審核人
class Approver
{
public:
Approver(string strName):m_strName(strName){}
//審核請求,打印信息
virtual void DealRequest(Request* pRequest)
{
cout << "Request " << pRequest->GetID() << " Approved by " << m_strName << endl;
}
private:
string m_strName;//審核人的名字
};
//假期請求
class HolidayRequest : public Request
{
public:
//構(gòu)造時指定請求ID和審核人
HolidayRequest(int iNO, Approver* pApprover):Request(iNO), m_pApprover(pApprover){}
//請求被處理
virtual void Execute()
{
m_pApprover->DealRequest(this);
}
private:
Approver* m_pApprover;
};
//匯總請求者
class Invoker
{
public:
//收集請求
void AddReq(Request* pReq)
{
m_vecReq.push_back(pReq);
}
//統(tǒng)一申請
void InvokeAllReq()
{
for_each(m_vecReq.begin(), m_vecReq.end(),Invoke);
}
private:
static void Invoke(Request* pReq)
{
if(pReq)
{
pReq->Execute();
}
}
vector<Request*> m_vecReq;
};
主函數(shù)中的使用
int main()
{
//假設(shè)有兩個經(jīng)理負責(zé)審批狭握,分別叫Mark和Nancy
Approver* pManagerMark = new Approver("Mark");
Approver* pManagerNancy = new Approver("Nancy");
//一個請求收集者
Invoker* pInvoker = new Invoker();
pInvoker->AddReq(new HolidayRequest(1, pManagerMark));
pInvoker->AddReq(new HolidayRequest(2, pManagerMark));
pInvoker->AddReq(new HolidayRequest(3, pManagerNancy));
pInvoker->AddReq(new HolidayRequest(4, pManagerNancy));
//收集所有請求后統(tǒng)一送去審批
pInvoker->InvokeAllReq();
return 0;
}
控制臺輸出結(jié)果
Request 1 Approved by Mark
Request 2 Approved by Mark
Request 3 Approved by Nancy
Request 4 Approved by Nancy
嗯 ~ 現(xiàn)在可以回去再看一遍文章開頭從GOF書中摘抄的描述了 ~
如有錯誤闪金,歡迎指正