責任鏈模式的定義
責任鏈模式定義如下:
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it. (使多個對象都有機會處理請求,從而避免了請求的發送者和接受者之間的耦合關一系。將這些對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有對象處理它為止。)
責任鏈模式的重點是在“鏈”上,由一條鏈去外理相似的請求在鏈中決定誰來處理這個請求,并返回相應的結果,其通用類圖如圖所示。
在責任鏈模式中一個請求發送到鏈中后,前一節點消費部分消息,然后交由后續節點繼續處理,最終可以有處理結果也可以沒有處理結果,讀者可以不用理會什么純的、不純的責任鏈模式。
在實際應用中,一般會有一個封裝類對責任模式進行封裝,也就是替代Client類,直接返回鏈中的第一個處理者,具體鏈的設置不需要高層次模塊關系,這樣,更簡化了高層次模塊的調用,減少模塊間的耦合,提高系統的靈活性。
責任鏈模式的應用
責任鏈模式的優點
責任鏈模式非常顯著的優點是將請求和處理分開。請求者可以不用知道是誰處理的,處理者可以不用知道請求的全貌(例如在J2EE項目開發中,可以剝離出無狀態Bean由責任鏈處理),兩者解耦,提高系統的靈活性。
責任鏈模式的缺點
責任鏈有兩個非常顯著的缺點:一是性能問題,每個請求都是從鏈頭遍歷到鏈尾,特別是在鏈比較長的時候,性能是一個非常大的問題。二是調試不很方便,特別是鏈條比較長,環節比較多的時候,由于采用了類似遞歸的方式,調試的時候邏輯可能比較復雜。
責任鏈模式的注意事項
鏈中節點數量需要控制,避免出現超長鏈的情況,一般的做法是在Handler中設置一個最大節點數量,在setNext方法中判斷是否已經是超過其閾值,超過則不允許該鏈建立,避免無意識地破壞系統性能。
最佳實踐
責任鏈模式屏蔽了請求的處理過程,你發起一個請求到底是誰處理的,這個你不用關心,只要你把請求拋給責任鏈的第一個處理者,最終會返回一個處理結果(當然也可以不做任何處理),作為請求者可以不用知道到底是需要誰來處理的,這是責任鏈模式的核心,同時責任鏈模式也可以作為一種補救模式來使用。
舉個簡單例子,如項目開發的時候,需求確認是這樣的:一個請求(如銀行客戶存款的幣種),一個處理者(只處理人民幣),但是隨著業務的發展(改 革開放了嘛,還要處理美元、日元等),處理者的數量和類型都有所增加,那這時候就可以在第一個處理者后面建立一個鏈,也就是責任鏈來處理請求,如果是人民幣,好,還是第一個業務邏輯來處理;如果是美元,好,傳遞到第二個業務邏輯來處理:日元、歐元……這些都不用在對原有的業務邏輯產生很大改變,通過擴展實現類就可以很好地解決這些需求變更的問題。