Java設(shè)計模式百例 - 責(zé)任鏈模式

本文源碼見:https://github.com/get-set/get-designpatterns/tree/master/chainofresponsibility

責(zé)任鏈模式(Chain of Responsibility Pattern)中兜畸,通常每個接收者都包含對另一個接收者的引用。如果一個對象不能處理該請求硫豆,那么它會把相同的請求傳給下一個接收者骂澄,依此類推边器。這種類型的設(shè)計模式屬于行為型模式兆龙。

例子

話不多說宛官,先看下邊兩個圖:

chainofresponsibility-example.png

相信你一眼就明白了媒咳,沒錯迹缀,這就是責(zé)任鏈模式的現(xiàn)實場景使碾。

  1. 第一個是公司內(nèi)的責(zé)任鏈圖,作為基層員工祝懂,許多事情要請示票摇。有些事情組長就可以做主,有些事情要部門經(jīng)理才能批準(zhǔn)嫂易,但是作為基層員工通常不會直接越級找部門經(jīng)理兄朋,而是通過上級層層上報。
  2. 第二個是空氣凈化器的凈化流程,先過濾大顆粒粉塵颅和,然后是小顆粒PM2.5傅事,然后是吸附甲醛和異味物質(zhì)...

這兩個例子有些明顯的區(qū)別:

  1. 第一個例子,每個環(huán)節(jié)并不一定要做具體處理峡扩,有的直接轉(zhuǎn)給下一個環(huán)節(jié)去處理蹭越;而第二個例子,每個環(huán)節(jié)都會做相應(yīng)處理教届。
  2. 第一個例子响鹃,到具體執(zhí)行環(huán)節(jié)處理完后,就不會再向下一個節(jié)點流轉(zhuǎn)案训;而第二個例子买置,空氣要做過每層過濾處理最終才能出來。

這兩種其實都是責(zé)任鏈模式强霎。也就是責(zé)任鏈模式不care上述這些(白眼忿项,那你說這么多,浪費哥的寶貴時間)城舞。責(zé)任鏈模型關(guān)注于單個環(huán)節(jié)轩触,而不是整體流程

chainofresponsibility.png

這是我直接從《Java與模式》中截的圖家夺,看到這里是不是有種“鏈表”的既視感脱柱,要想做成“鏈”,每個節(jié)點就要有下一個節(jié)點的引用拉馋,然后每個節(jié)點有相應(yīng)的處理方法榨为,好啦,齊活啦~那么流程鏈呢椅邓,由外部業(yè)務(wù)邏輯去實現(xiàn)就OK了柠逞。

下面這個具體的代碼例子,我也是拿來主義景馁,哈哈,不是今天偷懶逗鸣,而是感覺這個例子挺好合住,來自菜鳥教程的關(guān)于日志的例子

我們做應(yīng)用程序離不開日志撒璧,日志有多個等級透葛,通常從高到低有ERROR、WARN卿樱、INFO僚害、DEBUG等。

  1. 日志記錄的時候設(shè)置的等級越低繁调,那么就會記錄越多的日志萨蚕。比如要求日志記錄到DEBUG級靶草,那么ERROR、WARN岳遥、INFO奕翔、DEBUG這些日志都會打印出來;如果要求日志記錄到WARN級浩蓉,那么只打印出ERROR和WARN級別的日志派继。
  2. 日志打印在哪呢,有標(biāo)準(zhǔn)輸出捻艳、標(biāo)準(zhǔn)錯誤驾窟、文件等不同的輸出流。這些輸出流可以設(shè)置不同的日志級別认轨,就像上一條那樣绅络。

背景介紹完,可以看代碼了~

抽象類 AbstractLogger帶有詳細(xì)的日志記錄級別好渠。然后創(chuàng)建三種類型的記錄器昨稼,都擴展了AbstractLogger。每個記錄器消息的級別是否屬于自己的級別拳锚,如果是則相應(yīng)地打印出來假栓,否則將不打印并把消息傳給下一個記錄器。

chain_pattern_uml_diagram.jpg

創(chuàng)建抽象的記錄器類AbstractLogger霍掺,ConsoleLogger匾荆、ErrorLoggerFileLogger是擴展了的具體記錄器類。它們就是不同的責(zé)任鏈節(jié)點杆烁,根據(jù)自己的日志記錄級別打印出日志牙丽。

拿來主義的代碼就不貼了哈,可以看一下這個鏈接兔魂。

總結(jié)

關(guān)于責(zé)任鏈模式想必你有了一個感性的認(rèn)識烤芦,我不喜歡在文章中羅列設(shè)計模式的各種角色、使用場景析校、優(yōu)點构罗、缺點,感性的理解最重要智玻,說到底對設(shè)計模式的理解是對面向?qū)ο笤O(shè)計原則的理解遂唧。一方面,設(shè)計模式不僅僅是這23種吊奢,另一方面盖彭,具體某種設(shè)計模式在使用時也會有不同變化,不同的設(shè)計模式也可以結(jié)合使用。

因此設(shè)計模式要抓住特征召边,就像美術(shù)功底不高的人素描畫人物我們覺得不像铺呵,但是畫簡筆畫的人抓住特征畫出來的動漫大頭人形象,我們一看就知道這是誰掌实。一樣的道理陪蜻。

責(zé)任鏈模式的特征就在于“鏈”。如何實現(xiàn)這個鏈呢贱鼻,就是通過節(jié)點“接力”宴卖,每個節(jié)點指定好下個節(jié)點,這樣串起來就好邻悬。像流水線一樣症昏,各個節(jié)點處理自己分內(nèi)的工作。

好處也是顯而易見的父丰,就像流水線肝谭,如果增加了一道工具,那么接在合適的流程位置即可蛾扇,對于責(zé)任鏈模式來說沒有任何影響攘烛,因為流水線的構(gòu)造是由業(yè)務(wù)邏輯定義的。

責(zé)任鏈模式在許多我們熟知的Java框架或技術(shù)中都有應(yīng)用镀首。

  1. 寫過Servlet的同學(xué)肯定對Filter都有印象坟漱,我們可以定義多個Filter,這些Filter串起來就是一個“FilterChain”更哄,來自瀏覽器的請求過來之后芋齿,首先經(jīng)過層層Filter處理,然后到達(dá)映射的Servlet成翩,感覺是不是有點像“空氣過濾器”懊倮Α?
  2. Tomcat中也應(yīng)用到了責(zé)任鏈模式麻敌,這個可能有些同學(xué)不太清楚栅炒。Tomcat是一個Servlet容器的實現(xiàn),我們編寫的Servlet就是用這個容器托管起來了术羔,請求進來之后职辅,由Tomcat接管,然后轉(zhuǎn)交給具體Servlet處理聂示,然后再有Tomcat將處理反饋發(fā)送回去。
  • 其實這個容器是由一層層的類似于“俄羅斯套娃”的容器嵌套而成的簇秒,配置過Tomcat的server.xml的同學(xué)可能有印象鱼喉,標(biāo)簽層級是<Server><Service><Engine><Host><Context></Context></Host></Engine></Service></Server>我們的應(yīng)用程序作為<Context>是配置在最里邊的。
  • 那么請求進來之后,如果經(jīng)過層層套娃到達(dá)最里邊的<Context>也就是我們的應(yīng)用呢扛禽?就是用的責(zé)任鏈模式锋边,從Engine到Host再到Context一直到Wrapper(是的,還有一層套娃编曼。豆巨。。)都通過一個鏈傳遞請求掐场。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末往扔,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子熊户,更是在濱河造成了極大的恐慌萍膛,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,919評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嚷堡,死亡現(xiàn)場離奇詭異蝗罗,居然都是意外死亡,警方通過查閱死者的電腦和手機蝌戒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評論 3 392
  • 文/潘曉璐 我一進店門串塑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人北苟,你說我怎么就攤上這事桩匪。” “怎么了粹淋?”我有些...
    開封第一講書人閱讀 163,316評論 0 353
  • 文/不壞的土叔 我叫張陵吸祟,是天一觀的道長。 經(jīng)常有香客問我桃移,道長屋匕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,294評論 1 292
  • 正文 為了忘掉前任借杰,我火速辦了婚禮过吻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蔗衡。我一直安慰自己纤虽,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,318評論 6 390
  • 文/花漫 我一把揭開白布绞惦。 她就那樣靜靜地躺著逼纸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪济蝉。 梳的紋絲不亂的頭發(fā)上杰刽,一...
    開封第一講書人閱讀 51,245評論 1 299
  • 那天菠发,我揣著相機與錄音,去河邊找鬼贺嫂。 笑死滓鸠,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的第喳。 我是一名探鬼主播糜俗,決...
    沈念sama閱讀 40,120評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼曲饱!你這毒婦竟也來了悠抹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,964評論 0 275
  • 序言:老撾萬榮一對情侶失蹤渔工,失蹤者是張志新(化名)和其女友劉穎锌钮,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體引矩,經(jīng)...
    沈念sama閱讀 45,376評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡梁丘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,592評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了旺韭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片氛谜。...
    茶點故事閱讀 39,764評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖区端,靈堂內(nèi)的尸體忽然破棺而出值漫,到底是詐尸還是另有隱情,我是刑警寧澤织盼,帶...
    沈念sama閱讀 35,460評論 5 344
  • 正文 年R本政府宣布杨何,位于F島的核電站,受9級特大地震影響沥邻,放射性物質(zhì)發(fā)生泄漏危虱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,070評論 3 327
  • 文/蒙蒙 一唐全、第九天 我趴在偏房一處隱蔽的房頂上張望埃跷。 院中可真熱鬧,春花似錦邮利、人聲如沸弥雹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽剪勿。三九已至,卻和暖如春方庭,著一層夾襖步出監(jiān)牢的瞬間窗宦,已是汗流浹背赦颇。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留赴涵,地道東北人。 一個月前我還...
    沈念sama閱讀 47,819評論 2 370
  • 正文 我出身青樓订讼,卻偏偏與公主長得像髓窜,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子欺殿,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,665評論 2 354

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

  • 從三月份找實習(xí)到現(xiàn)在寄纵,面了一些公司,掛了不少脖苏,但最終還是拿到小米程拭、百度、阿里棍潘、京東恃鞋、新浪、CVTE亦歉、樂視家的研發(fā)崗...
    時芥藍(lán)閱讀 42,243評論 11 349
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理恤浪,服務(wù)發(fā)現(xiàn),斷路器肴楷,智...
    卡卡羅2017閱讀 134,654評論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,806評論 6 342
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法水由,類相關(guān)的語法,內(nèi)部類的語法赛蔫,繼承相關(guān)的語法砂客,異常的語法,線程的語...
    子非魚_t_閱讀 31,625評論 18 399
  • 交易是枯燥的呵恢,按照交易系統(tǒng)交易更是獨孤的鞠值,你的每一次執(zhí)行都絕不允許心中有任何的想法,唯一能做的就是等待瑰剃。 交易系統(tǒng)...
    期老三說閱讀 463評論 0 1