摘要:簡(jiǎn)介職責(zé)鏈模式有時(shí)候也叫責(zé)任鏈模式,它是一種對(duì)象行為的設(shè)計(jì)模式。中的就是使用了責(zé)任鏈模式。純的責(zé)任鏈模式的實(shí)際例子很難找到,一般看到的例子均是不純的責(zé)任鏈模式的實(shí)現(xiàn)。如果堅(jiān)持責(zé)任鏈不純便不是責(zé)任鏈模式,那么責(zé)任鏈模式便不會(huì)有太大意義了。
Java設(shè)計(jì)模式之職責(zé)鏈模式
前幾天復(fù)習(xí)java的異常處理時(shí),接觸到了責(zé)任鏈模式。在企業(yè)級(jí)應(yīng)用中,從前臺(tái)發(fā)過來的請(qǐng)求在后臺(tái)拋出異常,異常處理的設(shè)計(jì)一般會(huì)用到責(zé)任鏈模式,比如sql異常并不會(huì)直接拋出給前臺(tái),而是經(jīng)過一系列的處理和再封裝,拋給前臺(tái)一個(gè)用戶可識(shí)別的異常信息。
簡(jiǎn)介職責(zé)鏈模式有時(shí)候也叫責(zé)任鏈模式,它是一種對(duì)象行為的設(shè)計(jì)模式。目的是:使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免請(qǐng)求的發(fā)送者和接收者之間的耦合關(guān)系,將這些對(duì)象連成一條鏈,并沿著這條鏈傳遞該請(qǐng)求,直到有一個(gè)對(duì)象處理它為止。發(fā)送請(qǐng)求的客戶端并不知道鏈上的哪個(gè)對(duì)象會(huì)處理這個(gè)請(qǐng)求,這使得系統(tǒng)在不影響客戶端的情況下動(dòng)態(tài)的組織和分配責(zé)任。
這里需要注意的是,職責(zé)鏈可以是一條直線、一個(gè)環(huán)鏈或者是一個(gè)樹結(jié)構(gòu)的一部分。
Tomcat中的Filter就是使用了責(zé)任鏈模式。
參與者職責(zé)鏈模式UML圖:
一個(gè)典型的職責(zé)鏈對(duì)象圖可能這樣的:
Handler:抽象處理者。定義一個(gè)處理請(qǐng)求的接口,如果需要,接口可以定義 出一個(gè)方法以設(shè)定和返回對(duì)下家的引用。這個(gè)角色通常由一個(gè)Java抽象類或者Java接口實(shí)現(xiàn)。上圖中Handler類的聚合關(guān)系給出了具體子類對(duì)下家的引用,抽象方法handleRequest()規(guī)范了子類處理請(qǐng)求的操作。
ConcreteHandler:具體處理者。具體處理者接受到請(qǐng)求后,可以選擇立即處理這個(gè)請(qǐng)求或者將請(qǐng)求傳遞給下家。由于具體處理者持有對(duì)下家的引用,因此,如果需要,具體處理者可以訪問下家。
Client:客戶端。向處理者提交請(qǐng)求對(duì)象。
代碼示例需求:部門搞活動(dòng)向公司申請(qǐng)經(jīng)費(fèi),金額小于1000的項(xiàng)目經(jīng)理就可以審批,小于2000的部門經(jīng)理可以審批,大于2000的只能總經(jīng)理審批。
這里就使用職責(zé)鏈模式。申請(qǐng)人提交給項(xiàng)目經(jīng)理申請(qǐng)經(jīng)費(fèi),項(xiàng)目經(jīng)理如果權(quán)限夠的話就審批,不夠的話就提交到上級(jí)領(lǐng)導(dǎo),依次類推,直到能夠處理請(qǐng)求為止。
代碼實(shí)現(xiàn):
Handler:審批人員的抽象父類
package com.wangjun.designPattern.chainOfResponsibility; public abstract class Handler { protected Handler successor; public abstract boolean handler(int fee); public abstract void setSuccessor(Handler successor); public abstract Handler getSuccessot(); }
ConcreteHandler1:項(xiàng)目經(jīng)理
package com.wangjun.designPattern.chainOfResponsibility; public class ProjectManager extends Handler { @Override public boolean handler(int fee) { if(fee <= 1000) { System.out.println("項(xiàng)目經(jīng)理:審批通過。金額:" + fee); return true; }else { System.out.println("金額大于1000,項(xiàng)目經(jīng)理無權(quán)審批,移交給部門經(jīng)理!"); setSuccessor(new DepartmentManager()); return successor.handler(fee); } } @Override public void setSuccessor(Handler successor) { this.successor = successor; } @Override public Handler getSuccessot() { return successor; } }
ConcreteHandler2:部門經(jīng)理
package com.wangjun.designPattern.chainOfResponsibility; public class DepartmentManager extends Handler { @Override public boolean handler(int fee) { if(fee <= 2000) { System.out.println("部門經(jīng)理:審批通過。金額:" + fee); return true; }else { System.out.println("金額大于2000,部門經(jīng)理無權(quán)審批,移交給總經(jīng)理!"); setSuccessor(new Manager()); return successor.handler(fee); } } @Override public void setSuccessor(Handler successor) { this.successor = successor; } @Override public Handler getSuccessot() { return successor; } }
ConcreteHandler3:總經(jīng)理
package com.wangjun.designPattern.chainOfResponsibility; public class Manager extends Handler { @Override public boolean handler(int fee) { if(fee <= 10000) { System.out.println("總經(jīng)理:審批通過。金額:" + fee); return true; }else { System.out.println("金額大于10000,審批不通過!申請(qǐng)金額:" + fee); return false; } } @Override public void setSuccessor(Handler successor) { this.successor = successor; } @Override public Handler getSuccessot() { return successor; } }
Client:客戶端申請(qǐng)費(fèi)用
package com.wangjun.designPattern.chainOfResponsibility; public class Client { public static void main(String[] args) { // 測(cè)試申請(qǐng)費(fèi)用列表 int[] arr = {500, 1500, 2500, 29000}; // 將申請(qǐng)?zhí)峤唤o的項(xiàng)目經(jīng)理 ProjectManager pm = new ProjectManager(); for(int i = 0; i < arr.length; i++) { System.out.println("第" + (i+1) + "筆費(fèi)用"); if(pm.handler(arr[i])) { System.out.println("申請(qǐng)經(jīng)費(fèi)成功!"); }else { System.out.print("申請(qǐng)經(jīng)費(fèi)失敗!"); } System.out.println(); } } }
運(yùn)行結(jié)果:
第1筆費(fèi)用 項(xiàng)目經(jīng)理:審批通過。金額:500 申請(qǐng)經(jīng)費(fèi)成功! 第2筆費(fèi)用 金額大于1000,項(xiàng)目經(jīng)理無權(quán)審批,移交給部門經(jīng)理! 部門經(jīng)理:審批通過。金額:1500 申請(qǐng)經(jīng)費(fèi)成功! 第3筆費(fèi)用 金額大于1000,項(xiàng)目經(jīng)理無權(quán)審批,移交給部門經(jīng)理! 金額大于2000,部門經(jīng)理無權(quán)審批,移交給總經(jīng)理! 總經(jīng)理:審批通過。金額:2500 申請(qǐng)經(jīng)費(fèi)成功! 第4筆費(fèi)用 金額大于1000,項(xiàng)目經(jīng)理無權(quán)審批,移交給部門經(jīng)理! 金額大于2000,部門經(jīng)理無權(quán)審批,移交給總經(jīng)理! 金額大于10000,審批不通過!申請(qǐng)金額:29000 申請(qǐng)經(jīng)費(fèi)失敗!總結(jié)
可以在一下情況下使用職責(zé)鏈模式:
有多個(gè)對(duì)象可以處理同一個(gè)請(qǐng)求,哪個(gè)對(duì)象處理請(qǐng)求在運(yùn)行時(shí)刻自動(dòng)確定;
你想在不明確指定接受者的情況下,向多個(gè)對(duì)象的一個(gè)提交請(qǐng)求;
可處理一個(gè)請(qǐng)求的對(duì)象集合應(yīng)被動(dòng)態(tài)指定。
純的與不純的責(zé)任鏈模式
一個(gè)純的責(zé)任鏈模式要求一個(gè)具體的處理者對(duì)象只能在兩個(gè)行為中選擇一個(gè):一是承擔(dān)責(zé)任,而是把責(zé)任推給下家。不允許出現(xiàn)某一個(gè)具體處理者對(duì)象在承擔(dān)了一部分責(zé)任后又 把責(zé)任向下傳的情況。
在一個(gè)純的責(zé)任鏈模式里面,一個(gè)請(qǐng)求必須被某一個(gè)處理者對(duì)象所接收;在一個(gè)不純的責(zé)任鏈模式里面,一個(gè)請(qǐng)求可以最終不被任何接收端對(duì)象所接收。
純的責(zé)任鏈模式的實(shí)際例子很難找到,一般看到的例子均是不純的責(zé)任鏈模式的實(shí)現(xiàn)。有些人認(rèn)為不純的責(zé)任鏈根本不是責(zé)任鏈模式,這也許是有道理的。但是在實(shí)際的系統(tǒng)里,純的責(zé)任鏈很難找到。如果堅(jiān)持責(zé)任鏈不純便不是責(zé)任鏈模式,那么責(zé)任鏈模式便不會(huì)有太大意義了。
loading...
后續(xù)研究一下tomcat的Filter機(jī)制。
參考:《設(shè)計(jì)模式》
https://blog.csdn.net/m136663...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/69452.html
摘要:想一想,這個(gè)和我們的迭代器模式有著異曲同工的妙處,迭代器模式同樣也是遍歷選出最優(yōu)解,但是相比而言,職責(zé)鏈模式的直觀性個(gè)書寫的幸福感是遠(yuǎn)遠(yuǎn)超過迭代器模式的。 職責(zé)鏈模式其實(shí)很好理解,由于一個(gè)鏈字出賣了它的靈魂。我們可以從這個(gè)字得到很大的提示。首先這個(gè)模式一定有傳遞性,而且,節(jié)點(diǎn)是可以重復(fù)拼接的,并且每個(gè)節(jié)點(diǎn)都具有一定的過濾功能,一定的職責(zé)。 是不是想起了組合模式里的一些內(nèi)容呢? 是的,他...
摘要:面向?qū)ο蟪R姷脑O(shè)計(jì)模式有策略模式模板方法觀察者模式責(zé)任鏈模式以及工廠模式,使用表達(dá)式函數(shù)式編程思維有助于避免面向?qū)ο箝_發(fā)中的那些固定代碼。 本文是一篇《Java 8實(shí)戰(zhàn)》的閱讀筆記,閱讀大約需要5分鐘。 有點(diǎn)標(biāo)題黨,但是這確實(shí)是我最近使用Lambda表達(dá)式的感受。設(shè)計(jì)模式是過去的一些好的經(jīng)驗(yàn)和套路的總結(jié),但是好的語言特性可以讓開發(fā)者不去考慮這些設(shè)計(jì)模式。面向?qū)ο蟪R姷脑O(shè)計(jì)模式有策略模式...
摘要:設(shè)計(jì)模式的類別設(shè)計(jì)模式一共分為種類型,共種。屬于結(jié)構(gòu)型的設(shè)計(jì)模式適配器模式橋接模式裝飾模式組合模式外觀模式享元模式代理模式。問題描述了應(yīng)該在何時(shí)使用設(shè)計(jì)模式。解決方案描述了設(shè)計(jì)的組成成分,它們之間的相互關(guān)系及各自的職責(zé)和協(xié)作方式。 設(shè)計(jì)模式概述 1. 設(shè)計(jì)模式是什么 我們?cè)谄綍r(shí)編寫代碼的過程中,會(huì)遇到各種各樣的問題,細(xì)想一下很多問題的解決思路大致一樣的,這時(shí)候你就可以把解決問題的思路整...
摘要:提交請(qǐng)求的對(duì)象并不明確知道哪一個(gè)對(duì)象將會(huì)處理它也就是該請(qǐng)求有一個(gè)隱式的接受者。 20190412期 設(shè)計(jì)模式-如何理解職責(zé)鏈模式? 定義: 使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免請(qǐng)求的發(fā)送者和接收者之間的耦合關(guān)系,將這些對(duì)象連成一條鏈,并沿著這條鏈傳遞該請(qǐng)求,直到有一個(gè)對(duì)象處理它為止 也就是說,請(qǐng)求以后,從第一個(gè)對(duì)象開始,鏈中收到請(qǐng)求的對(duì)象要么親自處理它,要么轉(zhuǎn)發(fā)給鏈中的下一個(gè)候選者。提...
摘要:推文用設(shè)計(jì)模式解構(gòu)三國是一種什么體驗(yàn)行為型設(shè)計(jì)模式一策略模式工廠模式優(yōu)化結(jié)構(gòu)狀態(tài)模式隨著狀態(tài)改變而改變行為。推文狀態(tài)機(jī)與狀態(tài)模式責(zé)任鏈模式多個(gè)對(duì)象依次處理請(qǐng)求前者指定后者。代理模式代理針對(duì)一個(gè)對(duì)象,為了增加控制等中介雙方都是多個(gè),為了解耦。 策略模式 選擇使用封裝好的一系列算法,可相互替換。 類比:商店[Context]買完衣服買單[Stratege](現(xiàn)金[Concrete Stra...
閱讀 3561·2023-04-26 02:10
閱讀 1299·2021-11-22 15:25
閱讀 1668·2021-09-22 10:02
閱讀 907·2021-09-06 15:02
閱讀 3469·2019-08-30 15:55
閱讀 600·2019-08-30 13:58
閱讀 2775·2019-08-30 12:53
閱讀 3042·2019-08-29 12:38