Java 編程之責任鏈模式

一、什么是責任鏈模式?

責任鏈模式(Chain of Responsibility Pattern) 是一種行為型設計模式,它讓多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關系。將這些對象連成一條鏈,沿著這條鏈傳遞請求,直到有對象處理它為止。一般用在如下的場景

  • 多個對象可以處理同一個請求,但具體由哪個處理方未確定;
  • 系統需動態指定處理者;
  • 想在運行時靈活地添加新的處理節點;
    可能比較抽象,今天本篇就以例子的方式,讓你快速理解到這些文字描述。

二、責任鏈例子

小張想請假,走公司流程:

小張 → 班組長 → 主管 → 部門經理 → 總經理
  • 小張請 1 天假,班組長就能批;
  • 請 3 天假,需要主管審批;
  • 請 7 天,得上總經理簽字。

這就是責任鏈流程。誰能處理就在哪停下,不能處理就往上交

三、UML結構圖

在這里插入圖片描述
在這里插入圖片描述

  • Handler 定義處理請求的接口;
  • 每個 Leader 具體處理不同級別的請求;
  • 請求不能處理時,傳給下一個節點。

四、代碼實現

抽象處理者

構建一個抽象的 Handler類。

// 抽象類,定義處理邏輯和下一個節點
public abstract class Handler {protected Handler next;public void setNext(Handler next) {this.next = next;}// 處理請求的方法public abstract void handleRequest(int leaveDays);
}

具體處理者

具體處理審批十各級審批人。

// 班組長處理1天以內的請假
public class TeamLeader extends Handler {@Overridepublic void handleRequest(int leaveDays) {if (leaveDays <= 1) {System.out.println("班組長批準了" + leaveDays + "天的請假");} else if (next != null) {System.out.println("班組長無權處理,轉交主管");next.handleRequest(leaveDays);}}
}
// 主管處理3天以內的請假
public class Supervisor extends Handler {@Overridepublic void handleRequest(int leaveDays) {if (leaveDays <= 3) {System.out.println("主管批準了" + leaveDays + "天的請假");} else if (next != null) {System.out.println("主管無權處理,轉交經理");next.handleRequest(leaveDays);}}
}
// 部門經理處理7天以內的請假
public class Manager extends Handler {@Overridepublic void handleRequest(int leaveDays) {if (leaveDays <= 7) {System.out.println("經理批準了" + leaveDays + "天的請假");} else if (next != null) {System.out.println("經理無權處理,轉交總經理");next.handleRequest(leaveDays);}}
}
// 總經理處理所有請假
public class GeneralManager extends Handler {@Overridepublic void handleRequest(int leaveDays) {System.out.println("總經理批準了" + leaveDays + "天的請假");}
}

構建責任鏈

客戶端調用。

public class Client {public static void main(String[] args) {// 構建鏈條:組長 → 主管 → 經理 → 總經理Handler leader = new TeamLeader();Handler supervisor = new Supervisor();Handler manager = new Manager();Handler generalManager = new GeneralManager();leader.setNext(supervisor);supervisor.setNext(manager);manager.setNext(generalManager);// 發起請求int[] testLeaves = {1, 2, 5, 10};for (int days : testLeaves) {System.out.println("申請" + days + "天請假:");leader.handleRequest(days);System.out.println("------");}}
}

具體輸出

申請1天請假:
班組長批準了1天的請假
------
申請2天請假:
班組長無權處理,轉交主管
主管批準了2天的請假
------
申請5天請假:
班組長無權處理,轉交主管
主管無權處理,轉交經理
經理批準了5天的請假
------
申請10天請假:
班組長無權處理,轉交主管
主管無權處理,轉交經理
經理無權處理,轉交總經理
總經理批準了10天的請假
------

五、鏈式構建器

責任鏈的高級寫法,可以使用鏈式調用簡化鏈條搭建:

leader.setNext(supervisor).setNext(manager).setNext(generalManager);

為此只需修改 setNext() 方法返回值:

public Handler setNext(Handler next) {this.next = next;return next;
}

六、責任鏈模式的優缺點

優點:

  • 解耦請求發送者和處理者
  • 動態組合鏈條結構,擴展性強
  • 處理流程清晰,符合現實邏輯

缺點:

  • 可能造成請求無人處理
  • 每個處理節點都必須處理轉發邏輯

七、實際應用場景

應用場景描述
Servlet Filter鏈請求在多個Filter間傳遞
Spring Security攔截鏈多個攔截器處理登錄/權限
日志記錄日志可傳給不同的輸出設備
OA審批流程按審批等級處理請假/報銷等

八、小結

責任鏈模式是非常貼近現實的模式之一,很多審批、攔截、處理流程都可以用它來建模。它解耦了處理者與請求者,使系統更靈活、可拓展。掌握此模式,是 Java 工程師進階之路的重要一環。

九、參考

《23種設計模式概覽》
在這里插入圖片描述

@startuml
title Java責任鏈模式結構圖(Handler責任鏈)abstract class Handler {+setNext(next: Handler)+handleRequest(request)-next: Handler
}class LeaderA {班組長
}
class LeaderB {部門主管
}
class LeaderC {總經理
}
class LeaderN {可以加更多節點......
}Handler <|-- LeaderA
Handler <|-- LeaderB
Handler <|-- LeaderCHandler <|-- "LeaderN"@enduml

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

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

相關文章

1、做中學 | 一年級上期 Golang簡介和安裝環境

一、什么是golang Golang&#xff0c;通常簡稱 Go&#xff0c;是由 Google 公司的 Robert Griesemer、Rob Pike 和 Ken Thompson 于 2007 年創建的一種開源編程語言&#xff0c;并在 2009 年正式對外公布。 已經有了很多編程語言&#xff0c;為什么還要創建一種新的編程語言&…

Linux--迷宮探秘:從路徑解析到存儲哲學

上一篇博客我們說完了文件系統在硬件層面的意義&#xff0c;今天我們來說說文件系統在軟件層是怎么管理的。 Linux--深入EXT2文件系統&#xff1a;數據是如何被組織、存儲與訪問的&#xff1f;-CSDN博客 &#x1f30c; 引言&#xff1a;文件系統的宇宙觀 "在Linux的宇宙中…

淘寶商品數據實時獲取方案|API 接口開發與安全接入

在電商數據獲取領域&#xff0c;除了官方 API&#xff0c;第三方數據 API 接入也是高效獲取淘寶商品數據的重要途徑。第三方數據 API 憑借豐富的功能、靈活的服務&#xff0c;為企業和開發者提供了多樣化的數據解決方案。本文將聚焦第三方數據 API 接入&#xff0c;詳細介紹其優…

什么是防抖和節流?它們有什么區別?

文章目錄 一、防抖&#xff08;Debounce&#xff09;1.1 什么是防抖&#xff1f;1.2 防抖的實現 二、節流&#xff08;Throttle&#xff09;2.1 什么是節流&#xff1f;2.2 節流的實現方式 三、防抖與節流的對比四、總結 在前端開發中&#xff0c;我們經常會遇到一些高頻觸發的…

Springboot集成阿里云OSS上傳

Springboot集成阿里云OSS上傳 API 接口描述 DEMO提供的四個API接口&#xff0c;支持不同方式的文件和 JSON 數據上傳&#xff1a; 1. 普通文件上傳接口 上傳任意類型的文件 2. JSON 字符串上傳接口 上傳 JSON 字符串 3. 單個 JSON 壓縮上傳接口 上傳并壓縮 JSON 字符串…

刪除大表數據注意事項

數據庫是否會因刪除操作卡死&#xff0c;沒有固定的 “安全刪除條數”&#xff0c;而是受數據庫配置、表結構、操作方式、當前負載等多種因素影響。以下是關鍵影響因素及實踐建議&#xff1a; 一、導致數據庫卡死的核心因素 硬件與數據庫配置 CPU / 內存瓶頸&#xff1a;刪除…

Redis 是單線程模型?|得物技術

一、背景 使用過Redis的同學肯定都了解過一個說法&#xff0c;說Redis是單線程模型&#xff0c;那么實際情況是怎樣的呢&#xff1f; 其實&#xff0c;我們常說Redis是單線程模型&#xff0c;是指Redis采用單線程的事件驅動模型&#xff0c;只有并且只會在一個主線程中執行Re…

[特殊字符] AIGC工具深度實戰:GPT與通義靈碼如何徹底重構企業開發流程

&#x1f50d; 第一模塊&#xff1a;理念顛覆——為什么AIGC不是“玩具”而是“效能倍增器”&#xff1f; ▍企業開發的核心痛點圖譜&#xff08;2025版&#xff09; ??研發效能瓶頸??&#xff1a;需求膨脹與交付時限矛盾持續尖銳&#xff0c;傳統敏捷方法論已觸天花板?…

(LeetCode 面試經典 150 題) 169. 多數元素(哈希表 || 二分查找)

題目&#xff1a;169. 多數元素 方法一&#xff1a;二分法&#xff0c;最壞的時間復雜度0(nlogn)&#xff0c;但平均0(n)即可。空間復雜度為0(1)。 C版本&#xff1a; int nnums.size();int l0,rn-1;while(l<r){int mid(lr)/2;int ans0;for(auto x:nums){if(xnums[mid]) a…

(17)java+ selenium->自動化測試-元素定位大法之By css上

1.簡介 CSS定位方式和xpath定位方式基本相同,只是CSS定位表達式有其自己的格式。CSS定位方式擁有比xpath定位速度快,且比CSS穩定的特性。下面詳細介紹CSS定位方式的使用方法。相對CSS來說,具有語法簡單,定位速度快等優點。 2.CSS定位優勢 CSS定位是平常使用過程中非常重要…

【軟考高級系統架構論文】企業集成平臺的技術與應用

論文真題 企業集成平臺是一個支持復雜信息環境下信息系統開發、集成和協同運行的軟件支撐環境。它基于各種企業經營業務的信息特征,在異構分布環境(操作系統、網絡、數據庫)下為應用提供一致的信息訪問和交互手段,對其上運行的應用進行管理,為應用提供服務,并支持企業信息…

i.MX8MP LVDS 顯示子系統全解析:設備樹配置與 DRM 架構詳解

&#x1f525; 推薦&#xff1a;《Yocto項目實戰教程&#xff1a;高效定制嵌入式Linux系統》 京東正版促銷&#xff0c;歡迎支持原創&#xff01; 鏈接&#xff1a;https://item.jd.com/15020438.html i.MX8MP LVDS 顯示子系統全解析&#xff1a;設備樹配置與 DRM 架構詳解 在…

keep-alive實現原理及Vue2/Vue3對比分析

一、keep-alive基本概念 keep-alive是Vue的內置組件&#xff0c;用于緩存組件實例&#xff0c;避免重復渲染。它具有以下特點&#xff1a; 抽象組件&#xff1a;自身不會渲染DOM&#xff0c;也不會出現在父組件鏈中包裹動態組件&#xff1a;緩存不活動的組件實例&#xff0c;…

安卓jetpack compose學習筆記-Navigation基礎學習

目錄 一、Navigation 二、BottomNavigation Compose是一個偏向靜態刷新的UI組件&#xff0c;如果不想要自己管理頁面切換的復雜狀態&#xff0c;可以以使用Navigation組件。 頁面間的切換可以NavHost&#xff0c;使用底部頁面切換欄&#xff0c;可以使用腳手架的bottomBarNav…

基于大數據技術的在UGC數據分析與路線推薦的研究

博主介紹&#xff1a;java高級開發&#xff0c;從事互聯網行業六年&#xff0c;熟悉各種主流語言&#xff0c;精通java、python、php、爬蟲、web開發&#xff0c;已經做了六年的畢業設計程序開發&#xff0c;開發過上千套畢業設計程序&#xff0c;沒有什么華麗的語言&#xff0…

flask通過表單自動產生get請求的參數、form表單實現POST請求的自動提交

通過表單自動產生get請求的參數 相關代碼如下&#xff1a; import flaskapp flask.Flask(__name__)app.route(/) def login():html <!DOCTYPE html><html lang"en"><head><meta charset"UTF-8"><title>flask表單實現get…

《情感反詐模擬器》2025學習版

1.2 專業內容支持 67篇情感詐騙案例研究14萬字心理學分析資料783條專業配音對白 二、安裝與運行 2.1 系統要求 最低配置&#xff1a; 顯卡&#xff1a;GTX 1060CPU&#xff1a;i5-8400存儲&#xff1a;25GB空間 2.2 運行步驟 解壓游戲文件&#xff08;21.7GB&#xff09;…

預訓練 vs. 微調:大模型落地的核心兩步,究竟有何不同?

在人工智能領域&#xff0c;尤其是自然語言處理&#xff08;NLP&#xff09;和計算機視覺&#xff08;CV&#xff09;&#xff0c;大型模型如GPT系列、BERT、Stable Diffusion等取得了令人矚目的成就。支撐這些模型廣泛應用的關鍵技術流程&#xff0c;通常包含兩個核心階段&…

微信原生小程序轉uniapp過程及錯誤總結

https://ask.dcloud.net.cn/article/35786 此文章尤為重要&#xff0c;可以使用輔助工具 1、this.setData 源代碼&#xff1a; this.setData({dateTime: obj.dateTime, });需更換為 this.dateTime obj.dateTime2、cookie問題 在此文章有解釋 https://blog.csdn.net/ni155…

關于Spring JBDC

一、什么是Spring JDBC&#xff1f; 什么是JDBC&#xff1f; JDBC&#xff08;Java Database Connectivity&#xff09;是 Java 語言訪問數據庫的標準 API&#xff0c;它定義了一組接口和類&#xff0c;允許 Java 程序與各種數據庫進行交互。JDBC 提供了執行 SQL 語句、處理結果…