將多個對象組成一條職責鏈,而後按照它們在職責鏈上的順序來逐個找出到底應該誰來負責。設計模式
弱化「請求方」和「處理方」之間的關聯關係,讓雙方各自都成爲可獨立複用的組件。
程序可對付其餘需求,如根據狀況不一樣,負責處理的對象也會發生變化的這種需求。框架
Trouble 表示發生的問題的類。它帶有問題的編號(number)
Support用來解決問題的抽象類
NoSupport用來解決問題的具體類(永遠不處理問題)
LimitSupport用來解決問題的具體(僅解決編號小於指定編號的問題)
OddSupport用來解決問題的具體(僅解決奇數編號問題)
SpecialSupport用來解決問題的具體(僅解決指定編號的問題)
Main製做Support職責鏈,製造問題並測試程序行爲。測試
下圖展現了各個責任鏈在調用下一個Support方法以前都會先調用自身的resolve方法。
設計
Handler角色定義了處理請求的接口(API)。Handler角色知道「下一個處理者」是誰,若是本身沒法處理請求,他會將請求轉給「下一個處理者」。固然,「下一個處理者」3d
Chain of responsibiliy模式最大的優勢在於弱化了發出請求的人(Client角色)和處理請求的人(ConcreteHandler)之間的關係。Client角色向第一個ConcreteHandler角色發出請求,而後會在職責鏈中傳播,直到某個ConcreteHandler角色處理該請求。
既然知道Chain of responsibiliy模式這麼偉大,那麼,若是它不存在,那麼咱們該如何處理請求呢?
很明顯,若是不採用推卸責任的方式去處理請求,那麼咱們就必須有這樣一個偉大的角色知道「誰應該處理什麼請求」。顯然,讓「發出請求的人」知道「誰應該處理該請求」,會下降其做爲可複用組件的獨立性。對象
在前面的示例程序中,問題解決的次序以下:
blog
可是假設上面的6個角色中的某些角色之間的關係可能會發生變化,若是委託推卸責任,就能根據狀況變化動態地重組職責鏈。
假設不使用責任鏈模式,而是在程序中下達死命令「某個程序須要誰處理」這樣的對應關係,那麼很難再程序運行中去改變請求的處理者。
一個很實在的栗子:chain of responsibility 模式在視窗系統中的發揮了很大的做用。接口
ConcreteHandler勇敢地說不,才能讓它專一於本身的工做,假如咱們不使用責任鏈模式,首先得有一個「選舉哪一個ConcreteHandler該負責什麼樣處理」的方法。或者是每一個ConcreteHandler本身負責「任務分配工做」,即「本身不能處理的轉交給別人」。ci
回答是確定的,接受到請求以後並不能立馬去處理請求,因此會致使延遲。若是說責任和處理者之間的關係是明確的,那麼咱們應該放棄Chain of responsibiliy模式。it
Handler角色會常常使用Composite 模式
有時會使用Command模式向Handler角色發送請求。
首先經過Main方法啓動項目,發送請求給doFilter完成項目的真正啓動,在這裏實現handler的初始化還有調用責任鏈,handler經過HandlerFactory定義了責任鏈規則。在這裏實現Handler有兩種方式:
1)自定義handler,如類圖中的DemoHandler;
2)調用Jfinal中handler; jfinal框架中有ContextPathHandler、FakeStaticHandler、ServerNameRedirect301Handler、ActionHandler,這些ConcreteHandler經過集成Handler,實現Handler中抽象Handle方法,完成責任的細分。