1. 程式人生 > >《設計模式》學習筆記——責任鏈模式

《設計模式》學習筆記——責任鏈模式

        責任鏈模式(Chain of Responsibility Pattern)為請求建立了一個接收者物件的鏈,這種模式給予請求的型別,對請求的傳送者和接收者進行解耦,屬於行為型模式。在這種模式中,通常每個接收者都包含對另一個接收者的引用。如果一個物件不能處理該請求,那麼它會把相同的請求傳給下一個接收者,依此類推。

意圖:     避免請求傳送者與接收者耦合在一起,讓多個物件都有可能接收請求,將這些物件連線成一條鏈.     並且沿著這條鏈傳遞請求,直到有物件處理它為止。主要解決:     職責鏈上的處理者負責處理請求,客戶只需要將請求傳送到職責鏈上即可.     無須關心請求的處理細節和請求的傳遞,所以職責鏈將請求的傳送者和請求的處理者解耦了。何時使用:

    在處理訊息的時候以過濾很多道。如何解決:     攔截的類都實現統一介面。關鍵程式碼:     Handler 裡面聚合它自己,在 HanleRequest 裡判斷是否合適,如果沒達到條件則向下傳遞,向誰傳遞之前 set 進去。應用例項:     1、紅樓夢中的"擊鼓傳花"。      2、JS 中的事件冒泡。     3、JAVA WEB 中 Apache Tomcat 對 Encoding 的處理,Struts2 的攔截器,jsp servlet 的 Filter。優點:      1、降低耦合度。它將請求的傳送者和接收者解耦。      2、簡化了物件。使得物件不需要知道鏈的結構。      3、增強給物件指派職責的靈活性。通過改變鏈內的成員或者調動它們的次序,允許動態地新增或者刪除責任。      4、增加新的請求處理類很方便。缺點: 
    1、不能保證請求一定被接收。      2、系統性能將受到一定影響,而且在進行程式碼除錯時不太方便,可能會造成迴圈呼叫。     3、可能不容易觀察執行時的特徵,有礙於除錯。使用場景:      1、有多個物件可以處理同一個請求,具體哪個物件處理該請求由執行時刻自動確定。      2、在不明確指定接收者的情況下,向多個物件中的一個提交一個請求。      3、可動態指定一組物件處理請求。

ChainOfResponsibilityPattern.h

#pragma once
#include<iostream>
#include<string>


//責任連結口,抽象類
class CarHandle
{
public: 
	CarHandle() { m_nextCarHandle = nullptr; }
	~CarHandle() {}
	virtual void  HandleCar()= 0;
	CarHandle*   setNextHandleCar(CarHandle * nextCarHandle)// 用於將責任向後傳遞
	{
		m_nextCarHandle = nextCarHandle;
		return m_nextCarHandle;
	}
private:
	
protected:
	CarHandle* m_nextCarHandle;		// 指向下一個鏈條節點的指標

};

// 子任務
class HeadCarHandle:public CarHandle
{
public:
	virtual void  HandleCar()
	{
		std::cout<<"HeadCarHandle HandleCar()"<<std::endl;
		//執行完成自己的人物後,如果需要向後傳遞則向後傳遞
		if (nullptr != m_nextCarHandle)
		{
			m_nextCarHandle->HandleCar();
		}
	}
private:
protected:

};
// 子任務
class BodyCarHandle :public CarHandle
{
public:
	virtual void  HandleCar()
	{
		std::cout << "BodyCarHandle HandleCar()" << std::endl;
		//執行完成自己的人物後,如果需要向後傳遞則向後傳遞
		if (nullptr != m_nextCarHandle)
		{
			m_nextCarHandle->HandleCar();
		}
	}
private:
protected:

};
// 子任務
class TailCarHandle :public CarHandle
{
public:
	virtual void  HandleCar() 
	{
		std::cout << "TailCarHandle HandleCar()" << std::endl;
		//執行完成自己的人物後,如果需要向後傳遞則向後傳遞
		if (nullptr != m_nextCarHandle)
		{
			m_nextCarHandle->HandleCar();
		}
	}
private:
protected:

};
class ChainOfResponsibilityPattern
{
public:
	ChainOfResponsibilityPattern() {};
	~ChainOfResponsibilityPattern() {};
};

ChainOfResponsibilityPattern.cpp

#include "ChainOfResponsibilityPattern.h"

mainTest.cpp

#include<iostream>
#include<string>
#include "ChainOfResponsibilityPattern.h"

int main(void)
{

	CarHandle* headCarHandle = new HeadCarHandle;
	CarHandle* bodyCarHandle = new BodyCarHandle;
	CarHandle* tailCarHandle = new TailCarHandle;

	// 建立任務處理的關係連結串列
	headCarHandle->setNextHandleCar(bodyCarHandle)->setNextHandleCar(tailCarHandle);
	// 開始工作
	headCarHandle->HandleCar();


	delete headCarHandle;
	delete bodyCarHandle;
	delete tailCarHandle;

	system("pause");
	return 0;  
}