Java設(shè)計(jì)模式之java責(zé)任鏈模式詳解
在本講,我們來(lái)學(xué)習(xí)一下行為型模式里面的第四個(gè)設(shè)計(jì)模式,即責(zé)任鏈模式。
概述
在學(xué)習(xí)責(zé)任鏈模式之前,我們先來(lái)看一下下面這段描述。
在現(xiàn)實(shí)生活中,常常會(huì)出現(xiàn)這樣的事例:一個(gè)請(qǐng)求有多個(gè)對(duì)象可以處理,但每個(gè)對(duì)象的處理?xiàng)l件或權(quán)限不同。例如,公司員工請(qǐng)假,可批假的領(lǐng)導(dǎo)有部門負(fù)責(zé)人、副總經(jīng)理、總經(jīng)理等,但是每個(gè)領(lǐng)導(dǎo)能批準(zhǔn)的天數(shù)不同,員工必須根據(jù)自己要請(qǐng)假的天數(shù)去找不同的領(lǐng)導(dǎo)簽名,也就是說(shuō)員工必須記住每個(gè)領(lǐng)導(dǎo)的姓名、電話和地址等信息,這增加了員工請(qǐng)假的難度。因?yàn)轭I(lǐng)導(dǎo)有很多,員工到底找哪位領(lǐng)導(dǎo)他還得自己判斷,所以這會(huì)顯得特別特別麻煩。這樣的例子還有很多,如找領(lǐng)導(dǎo)出差報(bào)銷、生活中的"擊鼓傳花"游戲等。
說(shuō)了這么多,不知你有沒(méi)有在公司請(qǐng)過(guò)假,要是你請(qǐng)過(guò)假,想想是不是這么一回事啊!很顯然,在該例子中,請(qǐng)假就是一個(gè)請(qǐng)求,而且多個(gè)對(duì)象都可以處理該請(qǐng)求,有部門負(fù)責(zé)人、副總經(jīng)理、總經(jīng)理等,他們都可以進(jìn)行批假,但是每個(gè)對(duì)象的處理?xiàng)l件或權(quán)限不同,比如部門負(fù)責(zé)人有可能只能批1~2天的假,一旦超過(guò)這一請(qǐng)假天數(shù),員工就得去找部門負(fù)責(zé)人的頂頭上司,也就是副總經(jīng)理了,要是還超過(guò)了副總經(jīng)理批假的一個(gè)范圍的話,那么員工就得再去找總經(jīng)理批假了,這是不是就增加了員工請(qǐng)假的難度啊!
既然問(wèn)題出現(xiàn)了,那么又該如何去解決呢?使用責(zé)任鏈模式。那什么又是責(zé)任鏈模式呢?下面我們就來(lái)看一看它的概念。
又名職責(zé)鏈模式,為了避免請(qǐng)求發(fā)送者與多個(gè)請(qǐng)求處理者耦合在一起,將所有請(qǐng)求的處理者通過(guò)前一個(gè)對(duì)象記住其下一個(gè)對(duì)象的引用而連成一條鏈;當(dāng)有請(qǐng)求發(fā)生時(shí),可將請(qǐng)求沿著這條鏈傳遞,直到有對(duì)象處理它為止。
很多人看完,完全不知道啥意思,這里我就為大家稍微解釋解釋。就以員工請(qǐng)假案例來(lái)說(shuō),請(qǐng)求發(fā)送者指的就是員工,因?yàn)槭菃T工(例如張三)要請(qǐng)假的;多個(gè)請(qǐng)求處理者指的是部門負(fù)責(zé)人、副總經(jīng)理、總經(jīng)理等這些人。這樣,張三請(qǐng)假的示意圖就是下面這樣了。
從上圖中可以看到,張三要請(qǐng)假的話,那么他只需要去找自己部門的負(fù)責(zé)人就可以了,因?yàn)閷?duì)于他來(lái)說(shuō),他肯定知道自己部門的負(fù)責(zé)人是誰(shuí)。然后,部門負(fù)責(zé)人會(huì)根據(jù)張三請(qǐng)假的天數(shù)來(lái)決定是否批假,如果部門負(fù)責(zé)人能批假,那么自然就幫張三批了;可如果他不能批,那么他就會(huì)去找他的頂頭上司,即副總經(jīng)理,因?yàn)樗麄円呀?jīng)連成一條鏈了。同理,副總經(jīng)理也是一樣,他也會(huì)根據(jù)他所能批準(zhǔn)的請(qǐng)假天數(shù)來(lái)判斷,如果在自己的批準(zhǔn)范圍之內(nèi),那么廢話不多說(shuō),直接批假;如果批不了的話,那么再去找對(duì)應(yīng)他的頂頭上司,即總經(jīng)理。于此一來(lái),當(dāng)整個(gè)鏈走完,張三請(qǐng)假的流程就算是結(jié)束了。
理解了責(zé)任鏈模式的概念之后,接下來(lái),我們?cè)賮?lái)看一下責(zé)任鏈模式的結(jié)構(gòu)。
結(jié)構(gòu)
責(zé)任鏈模式主要包含以下角色:
- 抽象處理者(Handler)角色:定義一個(gè)處理請(qǐng)求的接口,包含抽象處理方法和一個(gè)后繼連接(即記住下一個(gè)對(duì)象的引用)。
注意了,對(duì)于該角色,我們既可以定義成接口,也可以定義成抽象類,一般來(lái)說(shuō),我們都會(huì)定義成抽象類。
- 具體處理者(Concrete Handler)角色:實(shí)現(xiàn)抽象處理者的處理方法,判斷能否處理本次請(qǐng)求,若可以處理請(qǐng)求則處理,否則將該請(qǐng)求轉(zhuǎn)給它的后繼者。
- 客戶類(Client)角色:創(chuàng)建處理鏈,并向鏈頭的具體處理者對(duì)象提交請(qǐng)求,它不關(guān)心處理細(xì)節(jié)和請(qǐng)求的傳遞過(guò)程。
也就是說(shuō),客戶類不需要去找對(duì)應(yīng)的對(duì)象進(jìn)行處理,而只需將處理鏈創(chuàng)建好即可。就拿上述張三請(qǐng)假的示意圖來(lái)說(shuō),他只需要找他自己的部門負(fù)責(zé)人即可,至于請(qǐng)假流程要經(jīng)過(guò)哪幾步,他并不需要去關(guān)注。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
mybatis返回map結(jié)果集@MapKey使用的場(chǎng)景分析
這篇文章主要介紹了mybatis返回map結(jié)果集@MapKey使用的場(chǎng)景分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01Maven安裝本地的jar包和創(chuàng)建帶模板的自定義項(xiàng)目的操作過(guò)程
這篇文章主要介紹了Maven安裝本地的jar包和創(chuàng)建帶模板的自定義項(xiàng)目,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-03-03idea中maven項(xiàng)目模塊變成灰色原因及解決方案
這篇文章主要介紹了idea中maven項(xiàng)目模塊變成灰色原因及解決方案,文中通過(guò)圖文結(jié)合的方式給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-03-03spring boot+spring cache實(shí)現(xiàn)兩級(jí)緩存(redis+caffeine)
這篇文章主要介紹了spring boot+spring cache實(shí)現(xiàn)兩級(jí)緩存(redis+caffeine),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-02-02springboot2.x 接入阿里云市場(chǎng)短信發(fā)送的實(shí)現(xiàn)
本文主要介紹了springboot2.x 接入阿里云市場(chǎng)短信發(fā)送的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11Spring中@Configuration注解和@Component注解的區(qū)別詳解
這篇文章主要介紹了Spring中@Configuration注解和@Component注解的區(qū)別詳解,@Configuration 和 @Component 到底有何區(qū)別呢?我先通過(guò)如下一個(gè)案例,在不分析源碼的情況下,小伙伴們先來(lái)直觀感受一下這兩個(gè)之間的區(qū)別,需要的朋友可以參考下2023-09-09Java動(dòng)態(tài)驗(yàn)證碼單線設(shè)計(jì)的兩種方法
這篇文章主要介紹了Java動(dòng)態(tài)驗(yàn)證碼單線設(shè)計(jì)的兩種方法,需要的朋友可以參考下2018-07-07