責任鏈模式_行為型_GOF23


責任鏈模式

責任鏈模式(Chain of Responsibility Pattern)是一種行為型設計模式,核心思想是將多個處理請求的對象連成一條鏈,請求沿鏈傳遞直到被處理。它像現實中的“多級審批流程”——請假或報銷時,申請會逐級提交給不同權限的領導,直到有人能處理為止。


一、通俗理解

假設你開發一個多級審批系統:

  1. 傳統方式:用大量 if-else 判斷不同金額的報銷單由誰審批,代碼臃腫且難以擴展。
  2. 責任鏈模式
    • 抽象審批人:定義統一的處理接口,并持有下一級審批人的引用。
    • 具體審批人(如組長、經理、CEO):各自處理權限內的請求,超出權限則轉交下一級。
      最終只需將審批人連成鏈,客戶端提交請求到鏈頭,無需關心具體處理細節。

二、模式結構
  1. 抽象處理者(Handler):定義處理請求的接口,包含設置下一處理者的方法(如 setNext())。
  2. 具體處理者(ConcreteHandler):實現處理邏輯,若無法處理則轉交下一級。
  3. 客戶端(Client):創建處理鏈,發起請求。

三、適用場景
  1. 多級審批流程:如請假、報銷、工單處理。
  2. 動態擴展處理邏輯:如日志過濾器、權限驗證鏈。
  3. 請求發送者與接收者解耦:如 GUI 事件傳遞、網絡請求攔截器。

四、代碼實現
1. C++ 示例(報銷審批鏈)
#include <iostream>  // 抽象處理者  
class Approver {  
protected:  Approver* next = nullptr;  
public:  void setNext(Approver* nextApprover) {  next = nextApprover;  }  virtual void handle(int amount) = 0;  
};  // 具體處理者:組長  
class GroupLeader : public Approver {  
public:  void handle(int amount) override {  if (amount <= 1000) {  std::cout << "組長審批通過(金額:" << amount << "元)" << std::endl;  } else if (next) {  next->handle(amount);  } else {  std::cout << "無人能處理此金額!" << std::endl;  }  }  
};  // 具體處理者:經理  
class Manager : public Approver {  
public:  void handle(int amount) override {  if (amount <= 5000) {  std::cout << "經理審批通過(金額:" << amount << "元)" << std::endl;  } else if (next) {  next->handle(amount);  }  }  
};  int main() {  GroupLeader leader;  Manager manager;  leader.setNext(&manager);  leader.handle(800);     // 組長處理  leader.handle(3000);    // 經理處理  leader.handle(10000);   // 無處理  return 0;  
}  

輸出

組長審批通過(金額:800元)  
經理審批通過(金額:3000元)  
無人能處理此金額!  

解析

  • 組長處理 ≤1000 元的請求,否則轉交經理。
  • 經理處理 ≤5000 元的請求,更高金額無后續處理者。

2. Python 示例(日志過濾器鏈)
from abc import ABC, abstractmethod  class LogHandler(ABC):  def __init__(self):  self.next = None  def set_next(self, next_handler):  self.next = next_handler  @abstractmethod  def handle(self, log_level, message):  pass  class DebugHandler(LogHandler):  def handle(self, log_level, message):  if log_level == "DEBUG":  print(f"[DEBUG] {message}")  elif self.next:  self.next.handle(log_level, message)  class ErrorHandler(LogHandler):  def handle(self, log_level, message):  if log_level == "ERROR":  print(f"[ERROR] {message}")  elif self.next:  self.next.handle(log_level, message)  # 客戶端  
debug = DebugHandler()  
error = ErrorHandler()  
debug.set_next(error)  debug.handle("DEBUG", "調試信息")  # [DEBUG] 調試信息  
debug.handle("ERROR", "系統崩潰")  # [ERROR] 系統崩潰  
debug.handle("INFO", "普通日志")   # 無輸出  

解析

  • DebugHandler 處理 DEBUG 日志,其他級別轉交下一處理者。
  • 鏈式調用避免硬編碼日志級別判斷。

3. Java 示例(請假審批系統)
// 抽象處理者  
abstract class Approver {  protected Approver next;  public void setNext(Approver next) {  this.next = next;  }  public abstract void handle(int days);  
}  // 具體處理者:組長  
class GroupLeader extends Approver {  @Override  public void handle(int days) {  if (days <= 3) {  System.out.println("組長批準請假 " + days + "天");  } else if (next != null) {  next.handle(days);  }  }  
}  // 具體處理者:經理  
class Manager extends Approver {  @Override  public void handle(int days) {  if (days <= 7) {  System.out.println("經理批準請假 " + days + "天");  } else if (next != null) {  next.handle(days);  }  }  
}  public class Client {  public static void main(String[] args) {  GroupLeader leader = new GroupLeader();  Manager manager = new Manager();  leader.setNext(manager);  leader.handle(2);  // 組長處理  leader.handle(5);  // 經理處理  leader.handle(10); // 無處理  }  
}  

輸出

組長批準請假 2天  
經理批準請假 5天  

解析

  • 組長處理 ≤3 天的請假,其余轉交經理。
  • 責任鏈動態組合,新增審批人只需擴展鏈。

五、優缺點分析
優點缺點
1. 解耦請求與處理邏輯:客戶端無需知道具體處理者1. 性能問題:長鏈可能導致請求傳遞慢
2. 靈活擴展:動態增減處理節點,符合開閉原則2. 調試困難:請求可能未被處理或循環傳遞
3. 單一職責:每個處理者專注自身邏輯3. 鏈配置錯誤風險:需確保鏈正確連接

六、總結

責任鏈模式通過鏈式傳遞請求,實現了處理邏輯的動態組合與解耦。適用于多級審批、日志過濾等場景,但需注意鏈長控制和錯誤處理。其核心價值在于:

  1. 靈活擴展:新增處理者無需修改原有代碼。
  2. 職責分離:每個處理者只關注自身任務。
  3. 實際應用:如 Spring MVC 的攔截器鏈、Netty 的 ChannelPipeline。

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

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

相關文章

Qt圖形化界面為何總被“冷落“?

在Qt開發者的IDE中&#xff0c;Qt Designer總像一個被遺忘的角落——即便它有著直觀的拖拽式界面設計功能。通過分析GitHub上超過5000個Qt項目發現&#xff0c;僅有17%的項目使用.ui文件構建界面。這個數據背后&#xff0c;隱藏著開發者群體對GUI構建方式的集體選擇。我們不禁要…

SQL Server從安裝到入門一文掌握應用能力。

本篇文章主要講解,SQL Server的安裝教程及入門使用的基礎知識,通過本篇文章你可以快速掌握SQL Server的建庫、建表、增加、查詢、刪除、修改等基本數據庫操作能力。 作者:任聰聰 日期:2025年3月31日 一、SQL Server 介紹: SQL Server 是微軟旗下的一款主流且優質的數據庫…

簡單視圖函數

視圖函數 文章目錄 視圖函數[toc]一、什么是視圖函數二、簡單視圖函數三、返回錯誤視圖 一、什么是視圖函數 所謂視圖函數&#xff08;簡稱視圖&#xff09;&#xff0c;本質上就是一個Python函數&#xff0c;用于接收Web請求并且返回Web響應。Web響應可以包含很多類型&#x…

QT文件操作(QT實操學習3)

1.項目架構 1.UI界面 1.新建文本文檔 2.打開文件 3.另存為文件 2.mainwindow.h? #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QFileDialog> #include <QMessageBox> #include <QDebug> QT_BEGIN_NAMESPACE namespa…

HX324雙運算放大器:賦能萬物互聯時代的信號處理基石

一、運算放大器行業的技術演進與市場需求 在全球半導體市場規模突破6000億美元的背景下&#xff0c;模擬芯片作為電子系統的"感官神經"&#xff0c;正迎來智能化升級浪潮。據IC Insights數據顯示&#xff0c;2023年全球運算放大器市場規模達32.7億美元&#xff0c;其…

C++ 結構體與函數

一.結構體 1.概念&#xff1a; 結構體&#xff08;struct&#xff09;是一種用戶自定義復合數據類型&#xff0c;其中可以包含不同類型的不同成員 2.結構體的應用場景&#xff1a; 我們在使用多個變量描述一個對象時&#xff0c;雖然也可以做到&#xff0c;但是難免顯得雜亂…

Python數據可視化-第1章-數據可視化與matplotlib

環境 開發工具 VSCode庫的版本 numpy1.26.4 matplotlib3.10.1 ipympl0.9.7教材 本書為《Python數據可視化》一書的配套內容&#xff0c;本章為第1章 數據可視化與matplotlib 本文主要介紹了什么是數據集可視化&#xff0c;數據可視化的目的&#xff0c;常見的數據可視化方式…

ESLint報錯:Could not find config file.

如果你的ESLint的版本大于 8&#xff0c;同時使用 .eslinrc.js 和 .eslintignore 作為配置文件&#xff0c;且目前用的是 VSCODE &#xff0c;就有可能遇到報錯&#xff1a; Could not find config file. 這個是因為 VSCode 中 ESLint 插件的配置 eslint.useFlatConfig 的問題…

基于SpringBoot的“醫療設備管理系統”的設計與實現(源碼+數據庫+文檔+PPT)

基于SpringBoot的“醫療設備管理系統”的設計與實現&#xff08;源碼數據庫文檔PPT) 開發語言&#xff1a;Java 數據庫&#xff1a;MySQL 技術&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系統展示 系統總體功能模塊圖 系統E-R圖 系統登錄界面 …

WordPress漢主題

WordPress漢主題wphan.com(以下簡稱WP漢主題)是一個專注于WordPress中文主題與插件開發的專業團隊。該團隊致力于為中文用戶提供高質量的WordPress主題和插件資源&#xff0c;幫助用戶輕松創建專業且吸引人的網站。 WP漢主題提供多種功能豐富的WordPress主題&#xff0c;涵蓋博…

arthas之jvm相關命令

文章目錄 1. dashboard2. thread線程相關3. jvmTHREAD相關文件描述符相關 4. sysprop5. 小結6. sysenv7. vmoption8. getstatic9. ognl10. 小結 1. dashboard 作用&#xff1a;顯示當前系統的實時數據面板&#xff0c;按q或ctrlc退出 數據說明 ID: Java級別的線程ID&#xff…

小米平板 4 Plus 玩機日志

在一次偶然中&#xff0c;我從一個角落中找到了這臺小米平板 4 Plus&#xff08;是的&#xff0c;現在正在用這個平板寫這篇文章&#xff09;。在找到她的時候&#xff0c;她已經奄奄一息了&#xff0c;即使按動那脆弱的電源鍵也沒有任何響應。 在給她補充能源后&#xff0c;她…

MSYS2學習筆記

前言 本文內容是MSys2 Documentation的學習筆記可以使用MSYS2編譯QGis 學習筆記 什么是MSYS2&#xff1f; MSYS2&#xff08;Minimal System 2&#xff09;是一個為Windows平臺打造的軟件開發環境和包管理系統&#xff0c;它結合了Cygwin的POSIX兼容層、Arch Linux的pacman…

gnvm切換node版本號

1. gnvm下載官網 GNVM - Node.js version manager on Windows by Go 2. 安裝 2.1 不存在 Node.js 環境 下載并解壓縮 gnvm.exe 保存到任意文件夾&#xff0c;并將此文件夾加入到環境變量 Path。 2.2 存在 Node.js 環境 下載并解壓縮 gnvm.exe 保存到 Node.js 所在的文件夾。 2.…

目標檢測 AP 計算 實例 python

以下是使用 Python 實現目標檢測中 ?Average Precision (AP)? 計算的完整實例&#xff0c;包含代碼和注釋。這里以 ?Pascal VOC 標準? 為例&#xff08;IoU閾值0.5&#xff09;。 步驟1&#xff1a;準備數據 假設&#xff1a; gt_boxes: 真實標注框列表&#xff0c;格式為 …

AWS用Glue讀取S3文件上傳數據到Redshift,再導出到Quicksight完整版,含VPC配置

1. 項目背景 AWS的官方文檔&#xff0c;關于Glue和Vpc配置部分已經比較舊了&#xff0c;按照官方文檔配置的流程始終跑不通&#xff0c;花了一番時間和波折后&#xff0c;才終于完整的跑通了。 在數據分析和商業智能&#xff08;BI&#xff09;領域&#xff0c;我們常需要將存…

SpringBoot詳細教程(持續更新中...)

SpringBoot 一、概述 Springboot有哪些特點呢&#xff1f;或者說它跟Spring比有哪些優點呢&#xff1f; 1、起步依賴 通俗的說&#xff0c;就是一個依賴包含了很多個依賴&#xff1b;好處是引入所需的依賴更加簡便&#xff0c;而且有效避免了依賴之間的版本沖突問題&#xf…

亞馬遜玩具品類技術驅動型選品策略:從趨勢洞察到合規基建

一、全球玩具電商技術演進趨勢 &#xff08;技術化重構原市場背景&#xff09; 數據可視化分析&#xff1a;通過亞馬遜SP-API抓取2023年玩具品類GMV分布熱力圖 監管技術升級&#xff1a; 美國CPSC啟用AI質檢系統&#xff08;缺陷識別準確率92.7%&#xff09; 歐盟EPR合規接口…

spring boot 整合redis

1.在pom文件中添加spring-boot-starter-data-redis依賴啟動器 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 2.編寫三個實體類 RedisHash("p…

python 語法篇(一)

目錄 1 正則匹配注意點11.1 正則匹配字符串寫法1.2 創建re函數&#xff08;1&#xff09;re.search()--搜索第一個匹配項&#xff08;2&#xff09;re.match() - 從字符串開頭匹配&#xff08;3&#xff09;re.findall() - 返回所有匹配項的列表&#xff08;4&#xff09;re.fi…