一. 概念
責(zé)任鏈模式(Chain of Responsibility Pattern)為請(qǐng)求創(chuàng)建了一個(gè)接收者對(duì)象的鏈。
定義: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.
意圖:避免請(qǐng)求發(fā)送者與接收者耦合在一起,讓多個(gè)對(duì)象都有可能接收請(qǐng)求,將這些對(duì)象連接成一條鏈,并且沿著這條鏈傳遞請(qǐng)求,直到有對(duì)象處理它為止。
主要解決:職責(zé)鏈上的處理者負(fù)責(zé)處理請(qǐng)求,客戶(hù)只需要將請(qǐng)求發(fā)送到職責(zé)鏈上即可,無(wú)須關(guān)心請(qǐng)求的處理細(xì)節(jié)和請(qǐng)求的傳遞,所以職責(zé)鏈將請(qǐng)求的發(fā)送者和請(qǐng)求的處理者解耦了。
何時(shí)使用:在處理消息的時(shí)候以過(guò)濾很多道。
如何解決:攔截的類(lèi)都實(shí)現(xiàn)統(tǒng)一接口。
關(guān)鍵代碼:Handler 里面聚合它自己,在 HanleRequest 里判斷是否合適,如果沒(méi)達(dá)到條件則向下傳遞,向誰(shuí)傳遞之前 set 進(jìn)去。
應(yīng)用實(shí)例: 1、紅樓夢(mèng)中的"擊鼓傳花"。 2、JS 中的事件冒泡。 3、JAVA WEB 中 Apache Tomcat 對(duì) Encoding 的處理,Struts2 的攔截器,jsp servlet 的 Filter。
優(yōu)點(diǎn): 1、降低耦合度。它將請(qǐng)求的發(fā)送者和接收者解耦。 2、簡(jiǎn)化了對(duì)象。使得對(duì)象不需要知道鏈的結(jié)構(gòu)。 3、增強(qiáng)給對(duì)象指派職責(zé)的靈活性。通過(guò)改變鏈內(nèi)的成員或者調(diào)動(dòng)它們的次序,允許動(dòng)態(tài)地新增或者刪除責(zé)任。 4、增加新的請(qǐng)求處理類(lèi)很方便。
缺點(diǎn): 1、不能保證請(qǐng)求一定被接收。 2、系統(tǒng)性能將受到一定影響,而且在進(jìn)行代碼調(diào)試時(shí)不太方便,可能會(huì)造成循環(huán)調(diào)用。 3、可能不容易觀察運(yùn)行時(shí)的特征,有礙于除錯(cuò)。
使用場(chǎng)景: 1、有多個(gè)對(duì)象可以處理同一個(gè)請(qǐng)求,具體哪個(gè)對(duì)象處理該請(qǐng)求由運(yùn)行時(shí)刻自動(dòng)確定。 2、在不明確指定接收者的情況下,向多個(gè)對(duì)象中的一個(gè)提交一個(gè)請(qǐng)求。 3、可動(dòng)態(tài)指定一組對(duì)象處理請(qǐng)求。
注意事項(xiàng):在 JAVA WEB 中遇到很多應(yīng)用。
二. 場(chǎng)景
三. 代碼
責(zé)任鏈模式,僅僅需要兩個(gè)類(lèi),一個(gè)抽象處理類(lèi),一個(gè)具體處理類(lèi)
抽象的處理類(lèi)實(shí)現(xiàn)三個(gè)職責(zé):
一是定義一個(gè)請(qǐng)求的處理方法handleMessage,唯一對(duì)外開(kāi)放的方法;
二是定義一個(gè)鏈的編排方法setNext,設(shè)置下一個(gè)處理者;
三是定義了具體的請(qǐng)求者必須實(shí)現(xiàn)的兩個(gè)方法:定義自己能夠處理的級(jí)別getHandlerLevel和具體的處理任務(wù)echo。
案例如下圖所示
