15、設計模式之責任鏈模式

責任鏈模式

顧名思義,責任鏈模式(Chain of Responsibility Pattern)為請求創建了一個接收者對象的鏈。這種模式給予請求的類型,對請求的發送者和接收者進行解耦。這種類型的設計模式屬于行為型模式。

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

介紹

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

主要解決: 職責鏈上的處理者負責處理請求,客戶只需要將請求發送到職責鏈上即可,無須關心請求的處理細節和請求的傳遞,所以職責鏈將請求的發送者和請求的處理者解耦了。

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

如何解決: 攔截的類都實現統一接口。

關鍵代碼: Handler 里面聚合它自己,在 HandlerRequest 里判斷是否合適,如果沒達到條件則向下傳遞,向誰傳遞之前 set 進去。

應用實例:

  1. JS 中的事件冒泡。
  2. spring 攔截器。
  3. JAVA WEB 中 Apache Tomcat 對 Encoding 的處理
  4. Struts2 的攔截器

優點:

  1. 降低耦合度。它將請求的發送者和接收者解耦。
  2. 簡化了對象。使得對象不需要知道鏈的結構。
  3. 增強給對象指派職責的靈活性。通過改變鏈內的成員或者調動它們的次序,允許動態地新增或者刪除責任。
  4. 增加新的請求處理類很方便。

缺點:

  1. 不能保證請求一定被接收。
  2. 系統性能將受到一定影響,而且在進行代碼調試時不太方便,可能會造成循環調用。
  3. 可能不容易觀察運行時的特征,有礙于除錯。

使用場景:

  1. 有多個對象可以處理同一個請求,具體哪個對象處理該請求由運行時刻自動確定。
  2. 在不明確指定接收者的情況下,向多個對象中的一個提交一個請求。
  3. 可動態指定一組對象處理請求。

注意事項: 在 JAVA WEB 中遇到很多應用。

主要涉及到以下幾個核心角色:

抽象處理者(Handler):

定義一個處理請求的接口,通常包含一個處理請求的方法(如 handleRequest)和一個指向下一個處理者的引用(后繼者)。
具體處理者(ConcreteHandler):

實現了抽象處理者接口,負責處理請求。如果能夠處理該請求,則直接處理;否則,將請求傳遞給下一個處理者。
客戶端(Client):
創建處理者對象,并將它們連接成一條責任鏈。通常,客戶端只需要將請求發送給責任鏈的第一個處理者,無需關心請求的具體處理過程。

代碼實現

以公司中的OA申請為例,有各種申請:請假、離職、團建、加班、購買設備等;不同申請需要的權限不一樣,需要審批的人不一樣。

定義申請類

/*** 申請*/
public class Petition {/*** 標題*/private String name;/*** 內容*/private String content;private Type type;/*** 申請人*/private String asker;public Petition(String name, String content, String asker, Type type) {this.name = name;this.content = content;this.asker = asker;this.type = type;}public String getName() {return name;}public String getContent() {return content;}public Type getType() {return type;}public String getAsker() {return asker;}public enum Type {/*** 請假*/LEAVE,/*** 加班*/OVERTIME,/*** 離職*/OFF_WORK,/*** 團建*/TRAVEL,/*** 購買設備*/BUY_EQUIPMENT,/*** 其他*/OTHER}
}

定義抽象職位


/***  職位*/
public abstract class Position {private Position nextPosition;public Position getNextPosition() {return this.nextPosition;}public Position nextPosition(Position nextPosition) {this.nextPosition = nextPosition;return this.nextPosition;}public abstract boolean handle(Petition petition);}

定義小組長,小組長只能審批類型為其他的申請

/*** 小組長*/
public class TeamLeader extends Position{@Overridepublic boolean handle(Petition petition) {if (petition.getType() == Petition.Type.OTHER){System.out.println("小組長審批" + petition.getName() + "通過");return true;}//小組長沒有權限,提交給上一級審批return getNextPosition().handle(petition);}
}

定義經理,經理能夠審批加班,請假,團建的申請

/*** 項目經理*/
public class Manager extends Position{@Overridepublic boolean handle(Petition petition) {if (petition.getType() == Petition.Type.OVERTIME|| petition.getType() == Petition.Type.LEAVE|| petition.getType() == Petition.Type.TRAVEL){System.out.println("項目經理審批" + petition.getName() + "通過");return true;}//項目經理沒有權限,提交給上一級審批return getNextPosition().handle(petition);}
}

定義總經理,能夠審批購買設備,離職的申請

/*** 總經理*/
public class GeneralManager extends Position{@Overridepublic boolean handle(Petition petition) {if (petition.getType() == Petition.Type.BUY_EQUIPMENT||petition.getType() == Petition.Type.OFF_WORK){System.out.println("總經理經理審批" + petition.getName() + "通過");return true;}else {System.out.println("總經理經理審批" + petition.getName() + "不通過");return false;}}
}

客戶端

public class Client {public static void main(String[] args) {Manager manager = new Manager();TeamLeader teamLeader = new TeamLeader();GeneralManager generalManager = new GeneralManager();//小組長上級項目經理,項目經理上級總經理teamLeader.nextPosition(manager).nextPosition(generalManager);teamLeader.handle(new Petition("Buy equipment", "I need to buy a new computer", "Jim", Petition.Type.BUY_EQUIPMENT));teamLeader.handle(new Petition("Leave", "I need to leave", "Jim", Petition.Type.LEAVE));teamLeader.handle(new Petition("Overtime", "I need to work overtime", "Jim", Petition.Type.OVERTIME));teamLeader.handle(new Petition("Off work", "I need to go off work", "Jim", Petition.Type.OFF_WORK));teamLeader.handle(new Petition("Travel", "I need to travel", "Jim", Petition.Type.TRAVEL));teamLeader.handle(new Petition("Other", "I need to do something else", "Jim", Petition.Type.OTHER));}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/16245.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/16245.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/16245.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

搜索引擎--ES基礎概念

ES是一款開源的搜索引擎&#xff0c;相比于mysql&#xff0c;它提供了非常強大的搜索功能 下面我們需要簡單的了解一下ES相比于mysql中的一些基本概念的區別&#xff1a; 首先我們要知道es在存儲數據的時候都是以json格式來存儲的 mysql <------> ES&#xff1a; table…

【九十四】【算法分析與設計】練習四蠻力法練習,排列問題和組合問題,求解最大連續子序列和問題,求解冪集問題,求解0/1背包問題,求解任務分配問題

求解最大連續子序列和問題 給定一個有n&#xff08;n≥1&#xff09;個整數的序列&#xff0c;要求求出其中最大連續子序列的和。 例如&#xff1a; 序列&#xff08;-2&#xff0c;11&#xff0c;-4&#xff0c;13&#xff0c;-5&#xff0c;-2&#xff09;的最大子序列和為20…

pymysql.err.OperationalError: (1030, ‘Got error 168 from storage engine‘)

錯誤 pymysql.err.OperationalError: (1030, Got error 168 from storage engine) 通常與MySQL的InnoDB存儲引擎相關&#xff0c;它指示你試圖進行的操作超出了存儲引擎的能力或資源限制。具體來說&#xff0c;MySQL錯誤代碼168&#xff08;或“ER_TABLE_NEEDS_UPGRADE”&#…

[處理器芯片]-6 超標量CPU實現之浮點運算

1 浮點運算單元FPU 超標量CPU中的浮點運算單元是專門處理浮點數運算的關鍵組件。浮點運算單元的設計涉及多個復雜的子模塊和技術&#xff0c;以保證高效、準確地執行浮點數的加減法、乘法、除法、平方根等操作。 1&#xff09;浮點數術語 浮點數通常采用IEEE 754標準表示&…

顯示IPS技術

顯示器的IPS&#xff08;In-Plane Switching&#xff0c;平面轉換&#xff09;技術是一種先進的液晶面板技術&#xff0c;由日立公司在2001年推出。該技術優化了液晶分子的排列方式&#xff0c;采取水平排列&#xff0c;使得分子結構在遇到外界壓力時仍能保持穩定&#xff0c;不…

第 33 次CCF認證

1. 詞頻統計 題目描述 樣例輸入 代碼 #include <bits/stdc.h>using namespace std;int main() {int n,m;cin>>n>>m;vector<int> ans1(m,0),ans2(m,0);while (n --) {int t;cin>>t;vector<int> vis(m1,0);for (int i 1;i < t;i ) {i…

python去除html中<div>等

用beautifulsoup并不能將全部的去除得到剩余的txt&#xff0c;特別在興趣段找關鍵字的時候。 使用re模塊可以實現這個功能。 for a in a_d:em_name str(a.find(em))pattern re.compile(r<[^>]>, re.S)result pattern.sub(, em_name)result result.strip(\n)name_…

Spring Boot 中的HTTP請求方式詳解:優缺點與代碼示例

在Spring Boot中&#xff0c;有多種方式可以發起HTTP請求。主要的工具包括RestTemplate、WebClient和增強的AsyncRestTemplate。本文將詳細介紹每種請求方式及其優缺點&#xff0c;并給出代碼示例。 1. RestTemplate RestTemplate 是 Spring 提供的一個用于同步 HTTP 請求的客…

vxe-table v4 ~ v4.6 升級到 v4.7+ 版本

vxe-table v4 ~ v4.6 升級到 v4.7 版本 更新日志 vxe-table 4.7 分離了 vxe-table 表格和 vxe-pc-ui 組件庫 變動如下 全局安裝 // ... import VxeUITable from vxe-table import vxe-table/lib/style.css // ...createApp(App).use(VxeUITable).mount(#app)修改后 // ...i…

數據結構(五)

數據結構&#xff08;五&#xff09; 常見的排序算法內部排序交換插入選擇歸并基數 外部排序基于歸并的 常見的排序算法 內部排序 交換 冒泡&#xff1a;每一次運行總會將最小的或者最大的放到前面&#xff0c;如果需要交換&#xff0c;一直在交換 快速排序*&#xff1a;經過…

【java程序設計期末復習】chapter5 子類的繼承

子類的繼承 繼承是一種由已有的類創建新類的機制。利用繼承&#xff0c;我們可以先創建一個共有屬性的一般類&#xff0c;根據該一般類再創建具有特殊屬性的新類&#xff0c;新類繼承一般類的狀態和行為&#xff0c;并根據需要增加它自己的新的狀態和行為。由繼承而得到的類稱…

Git分支的操作詳解(查看、新增、切換、合并、刪除)

天行健&#xff0c;君子以自強不息&#xff1b;地勢坤&#xff0c;君子以厚德載物。 每個人都有惰性&#xff0c;但不斷學習是好好生活的根本&#xff0c;共勉&#xff01; 文章均為學習整理筆記&#xff0c;分享記錄為主&#xff0c;如有錯誤請指正&#xff0c;共同學習進步。…

2024最新前端面試八股文【基礎篇293題】

?、HTML、HTTP、web綜合問題 1 前端需要注意哪些SEO 2 <img> 的 title 和 alt 有什么區別 3 HTTP的?種請求?法?途 4 從瀏覽器地址欄輸?url到顯示??的步驟 5 如何進??站性能優化 6 HTTP狀態碼及其含義 7 語義化的理解 8 介紹?下你對瀏覽器內核的理解 9 …

【操作系統】發展與分類(手工操作、批處理、分時操作、實時操作)

2.操作系統發展與分類 思維導圖 手工操作階段&#xff08;此階段無操作系統&#xff09; 需要人工干預 缺點&#xff1a; 1.用戶獨占全機&#xff0c;資源利用率低&#xff1b; 2.CPU等待手工操作&#xff0c;CPU利用不充分。 批處理階段&#xff08;操作系統開始出現&#x…

鏈表-線性表的鏈式表示

鏈表-線性表的鏈式表示 #mermaid-svg-ozpXrKnNCyYdqHvN {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ozpXrKnNCyYdqHvN .error-icon{fill:#552222;}#mermaid-svg-ozpXrKnNCyYdqHvN .error-text{fill:#552222;stro…

express 設定路徑別名

在使用ts情況下 pnpm i -D tsconfig-paths配置tsconfig.json {// 引入 tsconfig-paths/register// 注意 ts-node 的層級與 compilerOptions 相同"ts-node": {"require": ["tsconfig-paths/register"]},"compilerOptions": {// ...//…

width: auto 和 width: 100% 的區別

width: auto Vs. width: 100% 關于 width 屬性 CSS 中的 width 屬性用于設置元素的寬度。默認情況下&#xff0c;width 設置的是內容區&#xff08;content area&#xff09;的寬度。如果元素有樣式 box-sizing: border-box&#xff0c;則 width 設置的是邊框區&#xff08;bo…

正運動控制器:視覺糾偏和找孔

一、用戶主界面CCD參數設置 通過主界面CCD參數設置&#xff0c;學習如何操作計算相機中心與電批中心的偏移量&#xff0c;以及相機標定的功能。 1、相機中心與電批中心的偏移量計算 1.1、在用戶主界面點擊CCD參數按鈕&#xff0c;進入CCD設置界面。 主界面 CCD參數設置界面 1…

制作電子畫冊速成攻略,快來試試

?當今社會&#xff0c;數字媒體日益普及&#xff0c;電子畫冊作為一種嶄新的展示方式&#xff0c;受到了越來越多人的青睞。它不僅形式新穎&#xff0c;互動性強&#xff0c;而且制作起來也并不復雜。想知道如何快速掌握制作電子畫冊的技巧嗎&#xff1f;我來教你吧。 接下來&…