責(zé)任鏈模式

顧名思義畴蒲,責(zé)任鏈模式(Chain of Responsibility Pattern)為請求創(chuàng)建了一個接收者對象的鏈篇梭。這種模式給予請求的類型笆制,對請求的發(fā)送者和接收者進行解耦氮墨。這種類型的設(shè)計模式屬于行為型模式祝高。

在這種模式中栗弟,通常每個接收者都包含對另一個接收者的引用。如果一個對象不能處理該請求工闺,那么它會把相同的請求傳給下一個接收者乍赫,依此類推。

介紹

意圖:避免請求發(fā)送者與接收者耦合在一起陆蟆,讓多個對象都有可能接收請求雷厂,將這些對象連接成一條鏈,并且沿著這條鏈傳遞請求遍搞,直到有對象處理它為止罗侯。

主要解決:職責(zé)鏈上的處理者負責(zé)處理請求,客戶只需要將請求發(fā)送到職責(zé)鏈上即可溪猿,無須關(guān)心請求的處理細節(jié)和請求的傳遞钩杰,所以職責(zé)鏈將請求的發(fā)送者和請求的處理者解耦了。

何時使用:在處理消息的時候以過濾很多道诊县。

如何解決:攔截的類都實現(xiàn)統(tǒng)一接口讲弄。

關(guān)鍵代碼:Handler 里面聚合它自己,在 HandlerRequest 里判斷是否合適依痊,如果沒達到條件則向下傳遞避除,向誰傳遞之前 set 進去怎披。

應(yīng)用實例:?1、紅樓夢中的"擊鼓傳花"瓶摆。 2凉逛、JS 中的事件冒泡。 3群井、JAVA WEB 中 Apache Tomcat 對 Encoding 的處理状飞,Struts2 的攔截器,jsp servlet 的 Filter书斜。

優(yōu)點:?1诬辈、降低耦合度。它將請求的發(fā)送者和接收者解耦荐吉。 2焙糟、簡化了對象。使得對象不需要知道鏈的結(jié)構(gòu)样屠。 3穿撮、增強給對象指派職責(zé)的靈活性。通過改變鏈內(nèi)的成員或者調(diào)動它們的次序瞧哟,允許動態(tài)地新增或者刪除責(zé)任混巧。 4、增加新的請求處理類很方便勤揩。

缺點:?1咧党、不能保證請求一定被接收。 2陨亡、系統(tǒng)性能將受到一定影響傍衡,而且在進行代碼調(diào)試時不太方便,可能會造成循環(huán)調(diào)用负蠕。 3蛙埂、可能不容易觀察運行時的特征,有礙于除錯遮糖。

使用場景:?1绣的、有多個對象可以處理同一個請求,具體哪個對象處理該請求由運行時刻自動確定欲账。 2屡江、在不明確指定接收者的情況下,向多個對象中的一個提交一個請求赛不。 3惩嘉、可動態(tài)指定一組對象處理請求。

注意事項:在 JAVA WEB 中遇到很多應(yīng)用踢故。

實現(xiàn)

我們創(chuàng)建抽象類?AbstractLogger文黎,帶有詳細的日志記錄級別惹苗。然后我們創(chuàng)建三種類型的記錄器,都擴展了?AbstractLogger耸峭。每個記錄器消息的級別是否屬于自己的級別桩蓉,如果是則相應(yīng)地打印出來,否則將不打印并把消息傳給下一個記錄器抓艳。

步驟 1

創(chuàng)建抽象的記錄器類触机。

AbstractLogger.java

public abstract class AbstractLogger {

?public static int INFO = 1;

? public static int DEBUG = 2;

? public static int ERROR = 3;

? protected int level;

? //責(zé)任鏈中的下一個元素

? 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)建擴展了該記錄器類的實體類。

ConsoleLogger.java

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);

? }

}

ErrorLogger.java

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);

? }

}

FileLogger.java

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)建不同類型的記錄器玷或。賦予它們不同的錯誤級別,并在每個記錄器中設(shè)置下一個記錄器片任。每個記錄器中的下一個記錄器代表的是鏈的一部分偏友。

ChainPatternDemo.java

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 an 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 an debug level information.Standard Console::Logger: This is an 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.

本文轉(zhuǎn)載:https://www.runoob.com/design-pattern/design-pattern-intro.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末对供,一起剝皮案震驚了整個濱河市位他,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌产场,老刑警劉巖鹅髓,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異京景,居然都是意外死亡窿冯,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門确徙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來醒串,“玉大人,你說我怎么就攤上這事鄙皇∥叨模” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵伴逸,是天一觀的道長缠沈。 經(jīng)常有香客問我,道長错蝴,這世上最難降的妖魔是什么洲愤? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮漱竖,結(jié)果婚禮上禽篱,老公的妹妹穿的比我還像新娘。我一直安慰自己馍惹,他們只是感情好躺率,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布玛界。 她就那樣靜靜地躺著,像睡著了一般悼吱。 火紅的嫁衣襯著肌膚如雪慎框。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天后添,我揣著相機與錄音笨枯,去河邊找鬼。 笑死遇西,一個胖子當(dāng)著我的面吹牛馅精,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播粱檀,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼洲敢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了茄蚯?” 一聲冷哼從身側(cè)響起压彭,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎渗常,沒想到半個月后壮不,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡皱碘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年询一,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片尸执。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡家凯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出如失,到底是詐尸還是另有隱情绊诲,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布褪贵,位于F島的核電站掂之,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏脆丁。R本人自食惡果不足惜世舰,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望槽卫。 院中可真熱鬧跟压,春花似錦、人聲如沸歼培。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至查剖,卻和暖如春钾虐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背笋庄。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工效扫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人直砂。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓菌仁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親哆键。 傳聞我的和親對象是個殘疾皇子掘托,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容