深入理解Java責(zé)任鏈模式實(shí)現(xiàn)靈活的請求處理流程
介紹
責(zé)任鏈模式是一種行為型設(shè)計(jì)模式,其目的是將請求從一個對象傳遞到另一個對象,直到找到能夠處理該請求的對象為止.再責(zé)任鏈模式中,每個對象都持有對下一個對象的引用,形成一個鏈條.當(dāng)一個請求進(jìn)入這個鏈條時(shí),每個對象一次判斷是否有能力處理該請求,如果有,就處理該請求,如果沒有就將請求傳遞給下一個對象.這樣,直到找到能夠處理該請求的對象為止,或者請求無法被任何對象處理時(shí),責(zé)任鏈模式才結(jié)束.
實(shí)現(xiàn)
請求類型枚舉
public enum RequestType { TYPE_A, TYPE_B }
請求類
@Data public class Request { private RequestType requestType; private String content; public Request(RequestType requestType, String content) { this.requestType = requestType; this.content = content; } }
抽象處理類
@Data public abstract class Handler { protected Handler nextHandler; /** * 處理請求的方法 * * @param request */ public abstract void handle(Request request); }
具體處理類
public class ConcreteHandlerA extends Handler { /** * 處理請求的方法 * * @param request */ @Override public void handle(Request request) { if (request.getRequestType() == RequestType.TYPE_A) { // 處理請求 System.out.println("ConcreteHandlerA 處理了請求:" + request.getContent()); }else { // 將請求傳遞給下一個處理器 if (nextHandler != null){ nextHandler.handle(request); } } } } public class ConcreteHandlerB extends Handler{ /** * 處理請求的方法 * * @param request */ @Override public void handle(Request request) { if (request.getRequestType() == RequestType.TYPE_B) { // 處理請求 System.out.println("ConcreteHandlerB 處理了請求:" + request.getContent()); }else { // 將請求傳遞給下一個處理器 if (nextHandler != null){ nextHandler.handle(request); } } } }
測試
public class Demo { public static void main(String[] args) { // 創(chuàng)建責(zé)任鏈 Handler handlerA = new ConcreteHandlerA(); Handler handlerB = new ConcreteHandlerB(); handlerA.setNextHandler(handlerB); // 發(fā)送請求 Request request1 = new Request(RequestType.TYPE_A,"請求A"); handlerA.handle(request1); Request request2 = new Request(RequestType.TYPE_B,"請求B"); handlerA.handle(request2); Request request3 = new Request(RequestType.TYPE_A,"請求C"); handlerA.handle(request3); } }
我們可以看到,請求A被ConcreteHandlerA處理了,請求B被ConcreteHandlerB處理,請求C又被ConcreteHandlerA處理.這是因?yàn)槲覀儗oncreteHandlerA和ConcreteHandlerB連接成了一個責(zé)任鏈,請求會依次被傳遞給每個處理器,直到有一個處理器能夠處理它為止.如果沒有任何處理器能夠處理請求,請求將被忽略.
總結(jié)
優(yōu)點(diǎn)
- 解耦性強(qiáng):責(zé)任鏈模式能夠?qū)⒄埱笳吆吞幚碚呓怦?請求者無需知道請求的處理者是誰,處理者也無需知道請求的發(fā)送者是誰,從而降低了系統(tǒng)的耦合度
- 可擴(kuò)展性強(qiáng):責(zé)任鏈模式可以動態(tài)地增加,修改,刪除請求的處理者,系統(tǒng)的靈活性和可擴(kuò)展性得到了增強(qiáng)
- 代碼可讀性高:責(zé)任鏈模式能夠?qū)⒄埱筇幚砹鞒谭纸鉃槎鄠€小的處理單元,可以避免復(fù)雜的if-else嵌套,使得代碼更加清晰易讀.
缺點(diǎn)
- 可能會造成性能問題:當(dāng)責(zé)任鏈中的處理者過多或處理的任務(wù)比較耗時(shí)時(shí),可能會造成性能問題.
- 請求處理不一定會被處理:如果沒有處理者處理某個請求,那么該請求就會別丟棄,無法得到處理,可能會導(dǎo)致系統(tǒng)異常或出錯.
應(yīng)用場景
- 請求需要被多個對象處理:當(dāng)一個請求需要被多個對象處理時(shí),可以使用責(zé)任鏈模式.例如:一個事件發(fā)生后需要經(jīng)過多個對象處理,這些對象可以組成責(zé)任鏈,按順序處理該事件.
- 請求需要按順序被處理:當(dāng)一個請求需要按照一定的順序被處理時(shí),可以使用責(zé)任鏈模式.例如:多個對象需要按照某個順序依次處理請求,這些對象可以組成責(zé)任鏈,按順序處理請求.
- 動態(tài)添加請求處理者:當(dāng)需要動態(tài)添加,刪除或修改請求處理者時(shí),可以使用責(zé)任鏈模式.例如:需要動態(tài)地修改請求處理流程,可以通過修改責(zé)任鏈中的處理者來實(shí)現(xiàn).
- 需要避免請求發(fā)送者和接收者之間的耦合關(guān)系:當(dāng)需要避免請求發(fā)送者和接收者之間的耦合關(guān)系時(shí),可以使用責(zé)任鏈模式.例如:需要將請求發(fā)送者和接收者解耦,使得系統(tǒng)更加靈活,可擴(kuò)展.
到此這篇關(guān)于深入理解Java責(zé)任鏈模式實(shí)現(xiàn)靈活的請求處理流程的文章就介紹到這了,更多相關(guān)Java責(zé)任鏈模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis返回單個實(shí)體或者返回List的實(shí)現(xiàn)
這篇文章主要介紹了Mybatis返回單個實(shí)體或者返回List的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07SpringBoot集成P6Spy實(shí)現(xiàn)SQL日志的記錄詳解
P6Spy是一個框架,它可以無縫地?cái)r截和記錄數(shù)據(jù)庫活動,而無需更改現(xiàn)有應(yīng)用程序的代碼。一般我們使用的比較多的是使用p6spy打印我們最后執(zhí)行的sql語句2022-11-11springcloud安裝rabbitmq并配置延遲隊(duì)列插件的過程詳解
本期主要講解如何利用docker快速安裝rabbitmq并且配置延遲隊(duì)列插件,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05Java中IdentityHashMap與HashMap區(qū)別詳解
這篇文章主要介紹了Java中IdentityHashMap與HashMap區(qū)別詳解,很多人不曉得IdentityHashMap的存在,其中不乏工作很多年的Java開發(fā)者,他們看到就說是第三方j(luò)ar包,實(shí)際上它是Jdk源碼自帶的集合類,需要的朋友可以參考下2023-11-11Java發(fā)送帶html標(biāo)簽內(nèi)容的郵件實(shí)例代碼
下面小編就為大家?guī)硪黄狫ava發(fā)送帶html標(biāo)簽內(nèi)容的郵件實(shí)例代碼。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11Redisson分布式信號量RSemaphore的使用超詳細(xì)講解
這篇文章主要介紹了Redisson分布式信號量RSemaphore的使用,基于Redis的Redisson的分布式信號量RSemaphore采用了與java.util.concurrent.Semaphore相似的接口和用法2023-02-02基于springboot和redis實(shí)現(xiàn)單點(diǎn)登錄
這篇文章主要為大家詳細(xì)介紹了基于springboot和redis實(shí)現(xiàn)單點(diǎn)登錄,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06Spring的事件機(jī)制知識點(diǎn)詳解及實(shí)例分析
在本篇內(nèi)容里小編給大家分享的是一篇關(guān)于Spring的事件機(jī)制知識點(diǎn)詳解及實(shí)例分析,有需要的朋友么可以參考下。2021-12-12Java并發(fā)編程之ConcurrentLinkedQueue隊(duì)列詳情
這篇文章主要介紹了Java并發(fā)編程之ConcurrentLinkedQueue隊(duì)列詳情,ConcurrentLinkedQueue?內(nèi)部的隊(duì)列使用單向鏈表方式實(shí)現(xiàn),下文更多相關(guān)內(nèi)容敘述需要的小伙伴可以參考一下2022-04-04