定義
避免請求發(fā)送者與接收者 耦合在一起,讓多個對象都有可能接收請求花墩,將這些對象連接成一條鏈,并且沿著這條鏈傳 遞請求榛斯,直到有對象處理它為止观游。職責鏈模式是一種對象行為型模式。
UML類圖
image.png
角色和職能
- Handler(抽象處理者):它定義了一個處理請求的接口驮俗,一般設計為抽象類懂缕,由于不同的 具體處理者處理請求的方式不同,因此在其中定義了抽象請求處理方法王凑。因為每一個處理者 的下家還是一個處理者搪柑,因此在抽象處理者中定義了一個抽象處理者類型的對象(如結構圖 中的successor),作為其對下家的引用索烹。通過該引用工碾,處理者可以連成一條鏈。
- ConcreteHandler(具體處理者):它是抽象處理者的子類百姓,可以處理用戶請求渊额,在具體處理 者類中實現(xiàn)了抽象處理者中定義的抽象請求處理方法,在處理請求之前需要進行判斷垒拢,看是 否有相應的處理權限旬迹,如果可以處理請求就處理它,否則將請求轉發(fā)給后繼者;在具體處理 者中可以訪問鏈中下一個對象求类,以便請求的轉發(fā)奔垦。
設計核心
- 抽象處理者類定義了對下家的引用對象,以便將請求轉發(fā)給下家尸疆。
- 具體處理類的功能:
- 第一是處理請求椿猎,不同的具體處理者以 不同的形式實現(xiàn)抽象請求處理方法handleRequest()
- 第二是轉發(fā)請求,如果該請求超出了當前 處理者類的權限寿弱,可以將該請求轉發(fā)給下家犯眠。
總結
職責鏈模式通過建立一條鏈來組織請求的處理者,請求將沿著鏈進行傳遞症革,請求發(fā)送者無須 知道請求在何時筐咧、何處以及如何被處理,實現(xiàn)了請求發(fā)送者與處理者的解耦地沮。在軟件開發(fā) 中嗜浮,如果遇到有多個對象可以處理同一請求時可以應用職責鏈模式羡亩,例如在Web應用開發(fā)中創(chuàng) 建一個過濾器(Filter)鏈來對請求數(shù)據(jù)進行過濾,在工作流系統(tǒng)中實現(xiàn)公文的分級審批等等危融,使 用職責鏈模式可以較好地解決此類問題畏铆。
- 主要優(yōu)點
- 職責鏈模式使得一個對象無須知道是其他哪一個對象處理其請求,對象僅需知道該請求會 被處理即可吉殃,接收者和發(fā)送者都沒有對方的明確信息辞居,且鏈中的對象不需要知道鏈的結構, 由客戶端負責鏈的創(chuàng)建蛋勺,降低了系統(tǒng)的耦合度瓦灶。
- 請求處理對象僅需維持一個指向其后繼者的引用,而不需要維持它對所有的候選處理者的 引用抱完,可簡化對象的相互連接贼陶。
- 在給對象分派職責時,職責鏈可以給我們更多的靈活性巧娱,可以通過在運行時對該鏈進行動 態(tài)的增加或修改來增加或改變處理一個請求的職責碉怔。
- 在系統(tǒng)中增加一個新的具體請求處理者時無須修改原有系統(tǒng)的代碼,只需要在客戶端重新 建鏈即可禁添,從這一點來看是符合“開閉原則”的撮胧。
- 主要缺點
- 由于一個請求沒有明確的接收者,那么就不能保證它一定會被處理老翘,該請求可能一直到鏈 的末端都得不到處理;一個請求也可能因職責鏈沒有被正確配置而得不到處理芹啥。
- 對于比較長的職責鏈,請求的處理可能涉及到多個處理對象铺峭,系統(tǒng)性能將受到一定影響墓怀, 而且在進行代碼調試時不太方便。
- 如果建鏈不當逛薇,可能會造成循環(huán)調用捺疼,將導致系統(tǒng)陷入死循環(huán)疏虫。
適用場景
- 有多個對象可以處理同一個請求永罚,具體哪個對象處理該請求待運行時刻再確定,客戶端只需將請求提交到鏈上卧秘,而無須關心請求的處理對象是誰以及它是如何處理的呢袱。
- 在不明確指定接收者的情況下,向多個對象中的一個提交一個請求翅敌。
- 可動態(tài)指定一組對象處理請求羞福,客戶端可以動態(tài)創(chuàng)建職責鏈來處理請求,還可以改變鏈中 處理者之間的先后次序蚯涮。