深入理解Java責(zé)任鏈模式實(shí)現(xiàn)靈活的請(qǐng)求處理流程
介紹
責(zé)任鏈模式是一種行為型設(shè)計(jì)模式,其目的是將請(qǐng)求從一個(gè)對(duì)象傳遞到另一個(gè)對(duì)象,直到找到能夠處理該請(qǐng)求的對(duì)象為止.再責(zé)任鏈模式中,每個(gè)對(duì)象都持有對(duì)下一個(gè)對(duì)象的引用,形成一個(gè)鏈條.當(dāng)一個(gè)請(qǐng)求進(jìn)入這個(gè)鏈條時(shí),每個(gè)對(duì)象一次判斷是否有能力處理該請(qǐng)求,如果有,就處理該請(qǐng)求,如果沒(méi)有就將請(qǐng)求傳遞給下一個(gè)對(duì)象.這樣,直到找到能夠處理該請(qǐng)求的對(duì)象為止,或者請(qǐng)求無(wú)法被任何對(duì)象處理時(shí),責(zé)任鏈模式才結(jié)束.
實(shí)現(xiàn)
請(qǐng)求類型枚舉
public enum RequestType {
TYPE_A,
TYPE_B
}
請(qǐng)求類
@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;
/**
* 處理請(qǐng)求的方法
*
* @param request
*/
public abstract void handle(Request request);
}
具體處理類
public class ConcreteHandlerA extends Handler {
/**
* 處理請(qǐng)求的方法
*
* @param request
*/
@Override
public void handle(Request request) {
if (request.getRequestType() == RequestType.TYPE_A) {
// 處理請(qǐng)求
System.out.println("ConcreteHandlerA 處理了請(qǐng)求:" + request.getContent());
}else {
// 將請(qǐng)求傳遞給下一個(gè)處理器
if (nextHandler != null){
nextHandler.handle(request);
}
}
}
}
public class ConcreteHandlerB extends Handler{
/**
* 處理請(qǐng)求的方法
*
* @param request
*/
@Override
public void handle(Request request) {
if (request.getRequestType() == RequestType.TYPE_B) {
// 處理請(qǐng)求
System.out.println("ConcreteHandlerB 處理了請(qǐng)求:" + request.getContent());
}else {
// 將請(qǐng)求傳遞給下一個(gè)處理器
if (nextHandler != null){
nextHandler.handle(request);
}
}
}
}
測(cè)試
public class Demo {
public static void main(String[] args) {
// 創(chuàng)建責(zé)任鏈
Handler handlerA = new ConcreteHandlerA();
Handler handlerB = new ConcreteHandlerB();
handlerA.setNextHandler(handlerB);
// 發(fā)送請(qǐng)求
Request request1 = new Request(RequestType.TYPE_A,"請(qǐng)求A");
handlerA.handle(request1);
Request request2 = new Request(RequestType.TYPE_B,"請(qǐng)求B");
handlerA.handle(request2);
Request request3 = new Request(RequestType.TYPE_A,"請(qǐng)求C");
handlerA.handle(request3);
}
}

我們可以看到,請(qǐng)求A被ConcreteHandlerA處理了,請(qǐng)求B被ConcreteHandlerB處理,請(qǐng)求C又被ConcreteHandlerA處理.這是因?yàn)槲覀儗oncreteHandlerA和ConcreteHandlerB連接成了一個(gè)責(zé)任鏈,請(qǐng)求會(huì)依次被傳遞給每個(gè)處理器,直到有一個(gè)處理器能夠處理它為止.如果沒(méi)有任何處理器能夠處理請(qǐng)求,請(qǐng)求將被忽略.
總結(jié)
優(yōu)點(diǎn)
- 解耦性強(qiáng):責(zé)任鏈模式能夠?qū)⒄?qǐng)求者和處理者解耦,請(qǐng)求者無(wú)需知道請(qǐng)求的處理者是誰(shuí),處理者也無(wú)需知道請(qǐng)求的發(fā)送者是誰(shuí),從而降低了系統(tǒng)的耦合度
- 可擴(kuò)展性強(qiáng):責(zé)任鏈模式可以動(dòng)態(tài)地增加,修改,刪除請(qǐng)求的處理者,系統(tǒng)的靈活性和可擴(kuò)展性得到了增強(qiáng)
- 代碼可讀性高:責(zé)任鏈模式能夠?qū)⒄?qǐng)求處理流程分解為多個(gè)小的處理單元,可以避免復(fù)雜的if-else嵌套,使得代碼更加清晰易讀.
缺點(diǎn)
- 可能會(huì)造成性能問(wèn)題:當(dāng)責(zé)任鏈中的處理者過(guò)多或處理的任務(wù)比較耗時(shí)時(shí),可能會(huì)造成性能問(wèn)題.
- 請(qǐng)求處理不一定會(huì)被處理:如果沒(méi)有處理者處理某個(gè)請(qǐng)求,那么該請(qǐng)求就會(huì)別丟棄,無(wú)法得到處理,可能會(huì)導(dǎo)致系統(tǒng)異?;虺鲥e(cuò).
應(yīng)用場(chǎng)景
- 請(qǐng)求需要被多個(gè)對(duì)象處理:當(dāng)一個(gè)請(qǐng)求需要被多個(gè)對(duì)象處理時(shí),可以使用責(zé)任鏈模式.例如:一個(gè)事件發(fā)生后需要經(jīng)過(guò)多個(gè)對(duì)象處理,這些對(duì)象可以組成責(zé)任鏈,按順序處理該事件.
- 請(qǐng)求需要按順序被處理:當(dāng)一個(gè)請(qǐng)求需要按照一定的順序被處理時(shí),可以使用責(zé)任鏈模式.例如:多個(gè)對(duì)象需要按照某個(gè)順序依次處理請(qǐng)求,這些對(duì)象可以組成責(zé)任鏈,按順序處理請(qǐng)求.
- 動(dòng)態(tài)添加請(qǐng)求處理者:當(dāng)需要?jiǎng)討B(tài)添加,刪除或修改請(qǐng)求處理者時(shí),可以使用責(zé)任鏈模式.例如:需要?jiǎng)討B(tài)地修改請(qǐng)求處理流程,可以通過(guò)修改責(zé)任鏈中的處理者來(lái)實(shí)現(xiàn).
- 需要避免請(qǐng)求發(fā)送者和接收者之間的耦合關(guān)系:當(dāng)需要避免請(qǐng)求發(fā)送者和接收者之間的耦合關(guān)系時(shí),可以使用責(zé)任鏈模式.例如:需要將請(qǐng)求發(fā)送者和接收者解耦,使得系統(tǒng)更加靈活,可擴(kuò)展.
到此這篇關(guān)于深入理解Java責(zé)任鏈模式實(shí)現(xiàn)靈活的請(qǐng)求處理流程的文章就介紹到這了,更多相關(guān)Java責(zé)任鏈模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot使用easy-captcha 實(shí)現(xiàn)驗(yàn)證碼登錄功能(解決思路)
文章介紹了如何使用Spring Boot和Easy-Captcha實(shí)現(xiàn)驗(yàn)證碼登錄功能,后端通過(guò)Easy-Captcha生成驗(yàn)證碼并存儲(chǔ)在Redis中,前端獲取驗(yàn)證碼并顯示給用戶,登錄時(shí),前端將用戶輸入的驗(yàn)證碼和標(biāo)識(shí)符發(fā)送到后端進(jìn)行驗(yàn)證,感興趣的朋友跟隨小編一起看看吧2025-02-02
IDEA生成項(xiàng)目后出現(xiàn)的iml和idea文件問(wèn)題
這篇文章主要介紹了IDEA生成項(xiàng)目后出現(xiàn)的iml和idea文件問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
Java 滑動(dòng)窗口最大值的實(shí)現(xiàn)
這篇文章主要介紹了Java 滑動(dòng)窗口最大值,給定一個(gè)數(shù)組 nums,有一個(gè)大小為 k 的滑動(dòng)窗口從數(shù)組的最左側(cè)移動(dòng)到數(shù)組的最右側(cè)。感興趣的可以了解一下2021-05-05
java web實(shí)現(xiàn)簡(jiǎn)易收費(fèi)站
這篇文章主要為大家詳細(xì)介紹了java web實(shí)現(xiàn)簡(jiǎn)易收費(fèi)站,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一2020-11-11
mybatis自動(dòng)生成時(shí)如何設(shè)置不生成Example類詳解
這篇文章主要給大家介紹了關(guān)于mybatis自動(dòng)生成時(shí)如何設(shè)置不生成Example類的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-05-05
JavaCV與FFmpeg音視頻流處理技巧總結(jié)大全
JavaCV是一個(gè)開(kāi)源的Java接口,它為幾個(gè)著名的計(jì)算機(jī)視覺(jué)庫(kù)(如OpenCV、FFmpeg)提供了Java封裝,這篇文章主要給大家介紹了關(guān)于JavaCV與FFmpeg音視頻流處理技巧總結(jié)的相關(guān)資料,需要的朋友可以參考下2024-05-05
一篇文章帶你了解JAVA面對(duì)對(duì)象應(yīng)用
Java是一門(mén)面向?qū)ο蟮恼Z(yǔ)言。對(duì)象是Java程序中的基本實(shí)體。除了對(duì)象之外Java程序同樣處理基本數(shù)據(jù)。下面這篇文章主要給大家總結(jié)了關(guān)于Java中面向?qū)ο蟮闹R(shí)點(diǎn),需要的朋友可以參考借鑒,下面來(lái)一起看看吧2021-08-08
Java 實(shí)戰(zhàn)項(xiàng)目錘煉之仿天貓網(wǎng)上商城的實(shí)現(xiàn)流程
讀萬(wàn)卷書(shū)不如行萬(wàn)里路,只學(xué)書(shū)上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+jsp+servlet+mysql+ajax實(shí)現(xiàn)一個(gè)仿天貓網(wǎng)上商城項(xiàng)目,大家可以在過(guò)程中查缺補(bǔ)漏,提升水平2021-11-11
MyBatis常用的jdbcType數(shù)據(jù)類型
這篇文章主要介紹了MyBatis常用的jdbcType數(shù)據(jù)類型的相關(guān)資料,需要的朋友可以參考下2016-12-12

