1. 程式人生 > >設計模式---責任鏈模式(C++實現)

設計模式---責任鏈模式(C++實現)

責任鏈模式(Chain of Responsibility Pattern)為請求建立一個接受者物件的鏈。這種模式給與請求的型別,對請求的傳送者和接受者進行解耦。屬於行為型模式。

在這種模式中,通常每個接收者都包含對另一個接收者的引用。如果一個物件不能處理該請求,那麼它會把相同的請求傳給下一個接收者,依此類推。

意圖

避免請求傳送者和接受者耦合在一起,讓多個物件都有可能接收請求,將這些物件連線成一條鏈,並且沿著這條連傳遞請求,直到有物件處理它為止。

主要解決

職責鏈上的處理者負責處理請求,客戶只需要將請求傳送到職責鏈上即可,無須關心請求的處理細節和請求的傳遞,所以職責鏈將請求的傳送者和請求的處理者解耦了。

如何解決

攔截的類都統一實現介面

優點

1. 降低耦合度,它將請求的傳送者和接受者解耦

2. 簡化了物件,使得物件不需要知道鏈的結構

3.增強給物件指派職責的靈活性。通過改變鏈內的成員或者呼叫他們的次序,允許動態新增或刪除責任

4. 增加新的請求處理很方便

缺點

1. 不能保證請求一定會被接收;

2. 系統性能將受到一定的影響,而且在進行程式碼除錯時不太方便,可能造成迴圈呼叫

3. 可能不容易觀察執行時的 特徵,有礙於出錯

使用場景

1. 有多個物件可以處理同一個請求,具體哪個物件處理請求由執行時刻自動確定。

2. 在不明確指定接受者的 情況下,向多個物件中的一個提交一個請求。

3. 可動態指定一組物件處理請求

UML類圖:


C++實現

      舉個例子:

             以後上班的我想要請假這個流程是這樣的:首先我得向專案經理提交休假申請;我的專案經理 向 專案主管提交了我的休假申請,專案主管 向 部門經理提交我的休假申請;最後,部門經理同意了我的休假申請。那麼如果部門經理休假了,這個申請由誰來審批呢?這個時候就會交給專案主管進行審批。是挺麻煩的,但也是公司正常執行的必要。  在處理這個請假審批時,各個人員就好比在一條鏈上的節點,我不知道我的請求由誰審批,但是,我的請求最終會有人來處理的。這就是我想要實現的責任鏈模式。


 解釋: 對於每個角色,他們都有他們的職責;當我提交了休假申請時,專案經理需要判斷,看看自己能否處理,如果休假超過了2個小時,那麼專案經理就不能處理了;專案經理將這個請求提交到專案主管,專案主管判斷部門經理在不在,如果部門經理在,專案主管就不能處理了;最後,我的休假申請就到了部門經理那裡了,由他親自審批。可以很明顯的看到,專案經理、專案主管和部門經理都有可能處理我的休假申請,我的請求沿著這條鏈一直走下去,直到有人處理了我的請求。

code : 

//責任鏈模式

class HolidayRequest
{
public:
	HolidayRequest(int hour)
		:m_iHour(hour)
	{}
	int GetHour()
	{
		return m_iHour;
	}
private:
	int  m_iHour;
};

class Manager
{
public:
	virtual bool HandleRequest(HolidayRequest* request) = 0;
};

class PM : public  Manager   //PM:Project manager專案經理
{
public:
	PM(Manager* handler)
	:m_Handler(handler)
	{}
	bool HandleRequest(HolidayRequest* request)
	{
		if (request->GetHour() <= 2 || m_Handler == NULL)
		{
			cout << "PM said : OK" << endl;
			return true;
		}
		return m_Handler->HandleRequest(request);
	}
private:
	Manager* m_Handler;
};

class DM : public Manager //DM:Department Manager部門經理
{
public:
	DM(Manager* handler)
		:m_handler(handler)
	{}
	bool HandleRequest(HolidayRequest* request)
	{
		cout <<"DM   said :OK" << endl;
		return true;
	}
	bool IsIn()
	{
		return true;
	}
private:
	Manager *m_handler;
};

class PS : public Manager //Project Supervisor部門主管
{
public:
	PS(Manager* handler)
		:m_handler(handler)
	{}
	bool HandleRequest(HolidayRequest* request)
	{
		DM* pDM = dynamic_cast<DM* >(m_handler);
		if (pDM != NULL)
		{
			if (pDM->IsIn())
				return pDM->HandleRequest(request);
		}
		cout <<"PS  said :OK" << endl;
		return true;
	}
private:
	Manager* m_handler;
};


客戶端:

int tets_chain_of_Responsibility_Pattern()   //責任鏈模式
{
	DM* pDM = new DM(NULL);//部門經理
	PS* pPS= new PS(pDM);//部門主管
	PM* pPM = new PM(pPS);//專案經理
	HolidayRequest* Prequest = new HolidayRequest(10);
	pPM->HandleRequest(Prequest);
	delete Prequest;
	
	Prequest = new HolidayRequest(2);
	pPM->HandleRequest(Prequest);
	delete pDM;
	delete pPS;
	delete pPM;
	delete Prequest;

	system("pause");
	return 0;
}

總結

         責任鏈模式的實現時,需要處理好它的後繼者問題,也就是說,如果我不處理這個請求,那麼我將把這個請求發給誰去處理呢?同時,責任鏈模式在實現時,它的鏈的形狀不是職責鏈本身建立和維護的,而是由客戶進行建立的,這就大大提高了責任鏈的靈活性。

參考:

http://www.jellythink.com/archives/316