淺談JAVA 責(zé)任鏈模式
顧名思義,責(zé)任鏈模式(Chain of Responsibility Pattern)為請(qǐng)求創(chuàng)建了一個(gè)接收者對(duì)象的鏈。這種模式給予請(qǐng)求的類型,對(duì)請(qǐng)求的發(fā)送者和接收者進(jìn)行解耦。這種類型的設(shè)計(jì)模式屬于行為型模式。
在這種模式中,通常每個(gè)接收者都包含對(duì)另一個(gè)接收者的引用。如果一個(gè)對(duì)象不能處理該請(qǐng)求,那么它會(huì)把相同的請(qǐng)求傳給下一個(gè)接收者,依此類推。
介紹
意圖:
避免請(qǐng)求發(fā)送者與接收者耦合在一起,讓多個(gè)對(duì)象都有可能接收請(qǐng)求,將這些對(duì)象連接成一條鏈,并且沿著這條鏈傳遞請(qǐng)求,直到有對(duì)象處理它為止。
主要解決:
職責(zé)鏈上的處理者負(fù)責(zé)處理請(qǐng)求,客戶只需要將請(qǐng)求發(fā)送到職責(zé)鏈上即可,無(wú)須關(guān)心請(qǐng)求的處理細(xì)節(jié)和請(qǐng)求的傳遞,所以職責(zé)鏈將請(qǐng)求的發(fā)送者和請(qǐng)求的處理者解耦了。
何時(shí)使用:
在處理消息的時(shí)候以過濾很多道。
如何解決:
攔截的類都實(shí)現(xiàn)統(tǒng)一接口。
關(guān)鍵代碼:
Handler 里面聚合它自己,在 HandlerRequest 里判斷是否合適,如果沒達(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é)的靈活性。通過改變鏈內(nèi)的成員或者調(diào)動(dòng)它們的次序,允許動(dòng)態(tài)地新增或者刪除責(zé)任。
4、增加新的請(qǐng)求處理類很方便。
缺點(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)用。
實(shí)現(xiàn)
我們創(chuàng)建抽象類 AbstractLogger,帶有詳細(xì)的日志記錄級(jí)別。然后我們創(chuàng)建三種類型的記錄器,都擴(kuò)展了 AbstractLogger。每個(gè)記錄器消息的級(jí)別是否屬于自己的級(jí)別,如果是則相應(yīng)地打印出來(lái),否則將不打印并把消息傳給下一個(gè)記錄器。

步驟 1
創(chuàng)建抽象的記錄器類。
public abstract class AbstractLogger {
public static int INFO = 1;
public static int DEBUG = 2;
public static int ERROR = 3;
protected int level;
//責(zé)任鏈中的下一個(gè)元素
protected AbstractLogger nextLogger;
public void setNextLogger(AbstractLogger nextLogger){
this.nextLogger = nextLogger;
}
public void logMessage(int level, String message){
if(this.level <= level){
write(message);
}
if(nextLogger !=null){
nextLogger.logMessage(level, message);
}
}
abstract protected void write(String message);
}
步驟 2
創(chuàng)建擴(kuò)展了該記錄器類的實(shí)體類。
public class ConsoleLogger extends AbstractLogger {
public ConsoleLogger(int level){
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Standard Console::Logger: " + message);
}
}
public class ErrorLogger extends AbstractLogger {
public ErrorLogger(int level){
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Error Console::Logger: " + message);
}
}
public class FileLogger extends AbstractLogger {
public FileLogger(int level){
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("File::Logger: " + message);
}
}
步驟 3
創(chuàng)建不同類型的記錄器。賦予它們不同的錯(cuò)誤級(jí)別,并在每個(gè)記錄器中設(shè)置下一個(gè)記錄器。每個(gè)記錄器中的下一個(gè)記錄器代表的是鏈的一部分。
public class ChainPatternDemo {
private static AbstractLogger getChainOfLoggers(){
AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);
AbstractLogger fileLogger = new FileLogger(AbstractLogger.DEBUG);
AbstractLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO);
errorLogger.setNextLogger(fileLogger);
fileLogger.setNextLogger(consoleLogger);
return errorLogger;
}
public static void main(String[] args) {
AbstractLogger loggerChain = getChainOfLoggers();
loggerChain.logMessage(AbstractLogger.INFO, "This is an information.");
loggerChain.logMessage(AbstractLogger.DEBUG,
"This is a debug level information.");
loggerChain.logMessage(AbstractLogger.ERROR,
"This is an error information.");
}
}
步驟 4
執(zhí)行程序,輸出結(jié)果:
Standard Console::Logger: This is an information.
File::Logger: This is a debug level information.
Standard Console::Logger: This is a debug level information.
Error Console::Logger: This is an error information.
File::Logger: This is an error information.
Standard Console::Logger: This is an error information.
以上就是淺談JAVA 責(zé)任鏈模式的詳細(xì)內(nèi)容,更多關(guān)于JAVA 責(zé)任鏈模式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Java設(shè)計(jì)模式之java責(zé)任鏈模式詳解
- java設(shè)計(jì)模式責(zé)任鏈模式原理案例詳解
- 詳解Java實(shí)現(xiàn)設(shè)計(jì)模式之責(zé)任鏈模式
- Java設(shè)計(jì)模式之責(zé)任鏈模式詳解
- Java通俗易懂系列設(shè)計(jì)模式之責(zé)任鏈模式
- 一文搞懂Java設(shè)計(jì)模式之責(zé)任鏈模式
- Java設(shè)計(jì)模式之責(zé)任鏈模式的概念、實(shí)現(xiàn)以及netty中的責(zé)任鏈模式
- Java 設(shè)計(jì)模式之責(zé)任鏈模式及異步責(zé)任鏈詳解
相關(guān)文章
java split結(jié)果去除空字符串的方法實(shí)現(xiàn)
在Java開發(fā)中,我們經(jīng)常需要對(duì)字符串進(jìn)行分割操作,本文主要介紹了java split結(jié)果去除空字符串的方法實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2023-10-10
Springboot項(xiàng)目啟動(dòng)到一半卡住了,不報(bào)錯(cuò)問題及解決
這篇文章主要介紹了Springboot項(xiàng)目啟動(dòng)到一半卡住了,不報(bào)錯(cuò)問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
詳解SpringMVC 基礎(chǔ)教程 簡(jiǎn)單入門實(shí)例
這篇文章主要介紹了詳解SpringMVC 基礎(chǔ)教程 簡(jiǎn)單入門實(shí)例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2016-12-12
"Method?Not?Allowed"405問題分析以及解決方法
項(xiàng)目中在提交表單時(shí),提示“HTTP 405”錯(cuò)誤——“Method Not Allowed”這里顯示的是,方法不被允許,下面這篇文章主要給大家介紹了關(guān)于"Method?Not?Allowed"405問題分析以及解決方法的相關(guān)資料,需要的朋友可以參考下2022-10-10
SpringBoot實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換的項(xiàng)目實(shí)踐
在實(shí)際開發(fā)過程中,我們經(jīng)常遇到需要同時(shí)操作多個(gè)數(shù)據(jù)源的情況,本文主要介紹了SpringBoot實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換的項(xiàng)目實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下2024-04-04
Struts1教程之ActionMapping_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Struts1教程之ActionMapping,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2017-09-09
spring中12種@Transactional的失效場(chǎng)景(小結(jié))
日常我們進(jìn)行業(yè)務(wù)開發(fā)時(shí),基本上使用的都是聲明式事務(wù),即為使用@Transactional注解的方式,本文主要介紹了spring中12種@Transactional的失效場(chǎng)景,感興趣的小伙伴們可以參考一下2022-01-01

