責(zé)任鏈模式 Chain of Responsibility
剖析
意圖
- 給多個對象處理請求儡嘶,避免了接收請求的冗余。責(zé)任鏈接收對象并傳遞請求
- 面向?qū)ο笈c遞歸遍歷鏈表
定義
- 使用多個對象都有機會處理請求涛贯,從而避免請求的發(fā)送者和接受者之間的耦合關(guān)系妨马。將這個對象連成一條鏈盅视,并沿著這條鏈傳遞該請求枕稀,直到有一個對象處理它為止询刹。
本質(zhì)
- 分離職責(zé)谜嫉,動態(tài)組合
- 分離職責(zé)是前提,動態(tài)組合才是職責(zé)鏈模式的精華所在
模式講解
- 在標(biāo)準(zhǔn)的職責(zé)鏈模式中凹联,只要有對象處理了請求沐兰,這個請求就到此為止,不在被傳遞和處理了
客戶端發(fā)送請求蔽挠,總有一個隱式接收者處理請求
按照實現(xiàn)地方:
在實現(xiàn)客戶端提交請求錢組合鏈住闯。
可以再Handler里面實現(xiàn)鏈的組合,算是內(nèi)部鏈的一種
還有一種在各自的職責(zé)對象中澳淑,由各個職責(zé)對象自行決定后續(xù)處理對象比原。這種實現(xiàn)方式要求每個職責(zé)對象除了進(jìn)行業(yè)務(wù)處理外,還必須了解整個業(yè)務(wù)流程
數(shù)據(jù)來源:
一種在程序中動態(tài)組合
通過外部
通過配置文件傳遞進(jìn)來,流程的配置文件
按照設(shè)定好的條件來判斷請求對象在責(zé)任鏈模式中,請求不一定處理,因為可能沒有合適的處理者,請求在責(zé)任鏈中從頭到尾吕晌,每個處理對象都判斷都不屬于自己處理,最后請求就沒有對象來處理
UML
chain-uml.png
模式組成
- Handler:定義職責(zé)的接口作谭,通常在這里定義處理請求的方法洲赵,可以再這里實現(xiàn)后繼鏈
- ConcreteHandler: 實現(xiàn)職責(zé)的類,在這個類中识腿,實現(xiàn)對他職責(zé)范圍內(nèi)請求的處理出革,如果不處理,就繼續(xù)轉(zhuǎn)發(fā)請求給后繼者
- Client:職責(zé)鏈的客戶端渡讼,向鏈上的具體處理對象提交請求骂束,讓職責(zé)鏈負(fù)責(zé)處理
抽象處理類:抽象處理類中主要包含一個指向下一處理類的成員變量nextHandler和一個處理請求的方法handRequest,handRequest方法的主要主要思想是成箫,如果滿足處理的條件展箱,則有本處理類來進(jìn)行處理,否則由nextHandler來處理蹬昌。
*** 具體處理類***:具體處理類主要是對具體的處理邏輯和處理的適用條件進(jìn)行實現(xiàn)混驰。
抽象類實現(xiàn)三個職責(zé):
- 定義一個請求處理方法handleMessage 唯一對外開放的方法
- 定義一個鏈的編排方法setNext 設(shè)置下一個處理者;
- 定義了具體的請求者必須實現(xiàn)兩個方法:定義自己能夠處理的級別getHandlerLevel和具體的處理任務(wù)scho
例子
chain-example.png
場景
- 有多個對象可以處理請求皂贩,而處理程序只有在運行時才能確定栖榨。
- 向一組對象發(fā)生請求,而不想顯示指定處理請求的特定處理程序明刷。
- 想要動態(tài)制定處理一個請求的對象集合婴栽,可以使用職責(zé)鏈模式。
優(yōu)缺點
優(yōu)點
- 請求者和接收者松散耦合
- 動態(tài)組合職責(zé)
缺點
- 產(chǎn)生許多細(xì)粒度對象
- 不一定能背處理
- 性能問題
- 調(diào)試不方便
總結(jié)
- 責(zé)任鏈模式其實就是一個靈活版的if…else…語句辈末,它就是將這些判定條件的語句放到了各個處理類中愚争,這樣做的優(yōu)點是比較靈活了映皆,但同樣也帶來了風(fēng)險,比如設(shè)置處理類前后關(guān)系時准脂,一定要特別仔細(xì)劫扒,搞對處理類前后邏輯的條件判斷關(guān)系,并且注意不要在鏈中出現(xiàn)循環(huán)引用的問題狸膏。