設計模式——責任鏈設計模式(行為型)

摘要

責任鏈設計模式是一種行為型設計模式,旨在將請求的發送者與接收者解耦,通過多個處理器對象按鏈式結構依次處理請求,直到某個處理器處理為止。它包含抽象處理者、具體處理者和客戶端等核心角色。該模式適用于多個對象可能處理請求的場景,如風控系統中的貸款申請流程,通過鏈式組合處理整個流程。實現方式包括鏈式引用和集合遍歷等,適用于信貸申請風控校驗等實際應用。

1. 責任鏈設計模式定義

責任鏈設計模式(Chain of Responsibility Pattern)是一種行為型設計模式,允許多個處理器對象都有機會處理請求,避免請求的發送者與接收者之間的耦合關系。這些處理器按照鏈式結構連接,每個處理器決定是否處理請求,或將其傳遞給鏈上的下一個處理器。

1.1.1. ? 責任鏈設計模式定義要點:

項目

內容

目的

將請求的發送者與接收者解耦,讓多個對象有機會處理請求。

結構

每個處理者持有對下一個處理者的引用,形成鏈式結構。

核心機制

請求沿鏈傳遞,直到被某個處理者處理為止。

關鍵點

不關心請求由誰處理,處理器職責明確,鏈條可靈活組合。

1.1.2. ? UML 類圖核心角色:

  • Handler(抽象處理者):定義處理請求的接口,維護下一個處理者引用。
  • ConcreteHandler(具體處理者):實現處理邏輯,判斷是否處理請求,否則傳遞。
  • Client(客戶端):構建責任鏈并發起請求。

1.1.3. ? 示例場景說明(以風控為例):

風控系統中,一條貸款申請請求需要依次經過:

黑名單檢查 → 信用評分檢查 → 欺詐風險檢查 → 額度判斷

每個檢查環節都是一個責任節點,最終鏈式組合處理整個申請流程。

2. 責任鏈設計模式結構

2.1. 責任鏈設計模式類圖

  1. 處理者 (Handler) 聲明了所有具體處理者的通用接口。
  2. 基礎處理者 (Base Handler) 是一個可選的類, 你可以將所有處理者共用的樣本代碼放置在其中。
  3. 具體處理者 (Concrete Handlers) 包含處理請求的實際代碼。 每個處理者接收到請求后, 都必須決定是否進行處理, 以及是否沿著鏈傳遞請求。
  4. 客戶端 (Client) 可根據程序邏輯一次性或者動態地生成鏈。 值得注意的是, 請求可發送給鏈上的任意一個處理者, 而非必須是第一個處理者。

3. 責任鏈設計模式實現方式

責任鏈設計模式的實現方式有兩種主要形式:鏈式引用方式集合遍歷方式。在 Java 和 Spring 項目中,兩種方式都可以靈活使用,以下是詳細實現說明:

3.1. ? 鏈式引用方式(經典責任鏈)

3.1.1. 定義抽象處理器

public abstract class RiskHandler {protected RiskHandler next;public void setNext(RiskHandler next) {this.next = next;}public void handle(Request request) {if (doHandle(request) && next != null) {next.handle(request);}}protected abstract boolean doHandle(Request request);
}

3.1.2. 實現具體處理器

@Component
public class BlacklistHandler extends RiskHandler {@Overrideprotected boolean doHandle(Request request) {System.out.println("黑名單校驗");// 模擬通過return true;}
}@Component
public class CreditScoreHandler extends RiskHandler {@Overrideprotected boolean doHandle(Request request) {System.out.println("信用評分校驗");return true;}
}

3.1.3. 構造責任鏈(可由 Spring 初始化)

@Component
public class RiskChainBuilder {@Autowiredprivate BlacklistHandler blacklistHandler;@Autowiredprivate CreditScoreHandler creditScoreHandler;@PostConstructpublic void init() {blacklistHandler.setNext(creditScoreHandler);// 可繼續設置下一個}public RiskHandler getChain() {return blacklistHandler;}
}

3.2. ? 集合遍歷方式(策略+責任鏈)

這種方式更適合使用 Spring 管理 Bean。

3.2.1. 定義統一接口

public interface RiskHandler {boolean handle(Request request);
}

3.2.2. 實現多個處理器(用注解自動注入)

@Component
public class BlacklistHandler implements RiskHandler {public boolean handle(Request request) {System.out.println("黑名單處理");return true;}
}@Component
public class CreditHandler implements RiskHandler {public boolean handle(Request request) {System.out.println("信用處理");return true;}
}

3.2.3. 責任鏈執行器

@Component
public class RiskChainExecutor {@Autowiredprivate List<RiskHandler> handlers;public void process(Request request) {for (RiskHandler handler : handlers) {if (!handler.handle(request)) {break; // 攔截處理}}}
}

3.3. ? 責任鏈實現方式總結

項目

鏈式引用方式

集合遍歷方式

Spring友好

較差,需要手動串聯

非常友好,自動注入 List

動態配置順序

不方便(寫死在代碼)

可通過 @Order、配置排序

靈活性

靈活,可動態組合鏈

更適合順序一致、處理流程清晰

推薦程度

簡單鏈條推薦使用

企業級風控強烈推薦

4. 責任鏈設計模式適合場景

4.1. ? 適合使用責任鏈設計模式的場景

場景

說明

多個對象可以處理同一請求

請求的處理者不唯一,多個處理器具備處理能力。

處理邏輯具有先后順序且可拆分

如風控流程、審批流程、日志處理、事件流轉等。

希望動態添加或修改處理邏輯鏈

支持運行時動態組合處理器鏈條,提高靈活性。

解耦請求與處理器之間的關系

請求發送者無需知道誰會處理,只需交給鏈處理。

處理節點對請求是否繼續傳遞有決策權

允許部分處理節點終止請求,如認證失敗即停止。

4.2. ? 不適合使用責任鏈設計模式的場景

場景

原因

處理流程固定,結構簡單

使用責任鏈會增加結構復雜度,得不償失。

必須同時執行所有處理邏輯,不允許中斷

責任鏈是短路模型(遇到失敗可中斷),不適合要求“全部執行”的場景。

處理者之間高度耦合或依賴上下文共享

處理節點應獨立,依賴過多會降低可維護性。

對性能要求極高、鏈條很長

每次請求都需遍歷鏈條,可能帶來額外性能損耗。

請求必須同時由多個處理器并行處理

責任鏈是串行模式,不適合并行處理場景。

4.3. 📌 實際應用建議

使用責任鏈的條件

建議

節點解耦 + 處理器獨立 + 順序可變

? 可考慮使用

所有處理器必須全執行,順序固定

? 不推薦,改用責任集(全執行)或責任調度中心

所有邏輯都寫死在 if-else 中

? 可用責任鏈重構,提高擴展性和可維護性

5. 責任鏈設計模式實戰示例

5.1. ? 應用場景:信貸申請風控校驗

系統在用戶提交借款申請時,需要依次執行以下校驗邏輯(處理鏈):

  • 黑名單校驗
  • 實名認證校驗
  • 信用評分校驗

5.2. 🧩 請求對象

public class LoanRequest {private String userId;private String name;private int age;// 其他信息// getter/setter省略
}

5.3. 🧩 風控處理器接口

public interface RiskHandler {/*** 返回 true 表示通過校驗,繼續執行后續處理器;false 表示終止處理。*/boolean handle(LoanRequest request);
}

5.4. 🧩 風控處理器實現(舉例4個)

5.4.1. 🔹 黑名單校驗器

@Component
@Order(1)
public class BlacklistHandler implements RiskHandler {@Overridepublic boolean handle(LoanRequest request) {System.out.println("黑名單校驗: " + request.getUserId());// 假設用戶不在黑名單中return true;}
}

5.4.2. 🔹 實名認證校驗器

@Component
@Order(2)
public class RealNameHandler implements RiskHandler {@Overridepublic boolean handle(LoanRequest request) {System.out.println("實名認證校驗: " + request.getName());return true;}
}

5.4.3. 🔹 信用評分校驗器

@Component
@Order(3)
public class CreditScoreHandler implements RiskHandler {@Overridepublic boolean handle(LoanRequest request) {System.out.println("信用評分校驗: " + request.getUserId());return true;}
}

5.4.4. 🔹 反欺詐規則校驗器

@Component
@Order(4)
public class AntiFraudHandler implements RiskHandler {@Overridepublic boolean handle(LoanRequest request) {System.out.println("反欺詐校驗: " + request.getUserId());return true;}
}

5.5. 🧩 風控責任鏈執行器(接口變實現遍歷)

@Component
public class RiskCheckExecutor {@Autowiredprivate List<RiskHandler> handlers;public boolean execute(LoanRequest request) {for (RiskHandler handler : handlers) {if (!handler.handle(request)) {System.out.println("風控攔截,終止流程");return false;}}System.out.println("所有風控校驗通過");return true;}
}

@Order 確保處理器執行順序一致。

5.6. 🧩 測試調用示例(如用于 Controller)

@RestController
@RequestMapping("/loan")
public class LoanController {@Autowiredprivate RiskCheckExecutor executor;@PostMapping("/apply")public ResponseEntity<String> apply(@RequestBody LoanRequest request) {boolean pass = executor.execute(request);if (pass) {return ResponseEntity.ok("風控通過,進入審批");} else {return ResponseEntity.status(HttpStatus.FORBIDDEN).body("風控未通過");}}
}

5.7. ? 項目示例總結

特性

說明

注解注入

使用 @Component 注冊處理器,@Autowired注入集合

避免構造函數

所有注入均為字段注入,無需構造器方式

解耦結構

每個處理器職責單一,互不干擾

可擴展性

增加校驗邏輯僅需新增實現類并加上 @Component@Order

6. 責任鏈設計模式思考

博文參考

  • https://github.com/guanguans/design-patterns-for-humans-cn

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

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

相關文章

react/vue移動端項目,刷新頁面404的原因以及解決辦法

一 、 項目 移動端 二、背景 1、問題描述&#xff1a;react/vue移動端項目&#xff0c;正常的頁面操作跳轉&#xff0c;不會出現404的問題&#xff0c;但是一旦刷新&#xff0c;就會出現404報錯 2、產生原因&#xff1a; React Router是客戶端的路由&#xff0c;當再次刷新時…

數據結構-算法學習C++(入門)

目錄 03二進制和位運算04 選擇、冒泡、插入排序05 對數器06 二分搜索07 時間復雜度和空間復雜度08 算法和數據結構09 單雙鏈表09.1單雙鏈表及反轉09.2合并鏈表09.2兩數相加09.2分隔鏈表 013隊列、棧、環形隊列013.1隊列013.2棧013.3循環隊列 014棧-隊列的相互轉換014.1用棧實現…

用JS實現植物大戰僵尸(前端作業)

1. 先搭架子 整體效果&#xff1a; 點擊開始后進入主場景 左側是植物卡片 右上角是游戲的開始和暫停鍵 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevic…

深入理解設計模式之代理模式

深入理解設計模式之&#xff1a;代理模式 一、什么是代理模式&#xff1f; 代理模式&#xff08;Proxy Pattern&#xff09;是一種結構型設計模式。它為其他對象提供一種代理以控制對這個對象的訪問。代理對象在客戶端和目標對象之間起到中介作用&#xff0c;可以在不改變目標…

Ubuntu設置之初始化

安裝SSH服務 # 安裝 OpenSSH Server sudo apt update sudo apt install -y openssh-server# 檢查 SSH 服務狀態 sudo systemctl status ssh # Active: active (running) since Sat 2025-05-31 17:13:07 CST; 6s ago# 重啟服務 sudo systemctl restart ssh自定義分辨率 新…

【仿生機器人】極具前瞻性的架構——認知-情感-記憶“三位一體的仿生機器人系統架構

基于您的深度需求分析&#xff0c;我將為您設計一個全新的"認知-情感-記憶"三位一體的仿生機器人系統架構。以下是經過深度優化的解決方案&#xff1a; 一、核心架構升級&#xff08;三體認知架構&#xff09; 采用量子糾纏式架構設計&#xff1a; 認知三角&#xf…

Python量化交易12——Tushare全面獲取各種經濟金融數據

兩年前寫過Tushare的簡單使用&#xff1a; Python量化交易08——利用Tushare獲取日K數據_skshare- 現在更新一下吧&#xff0c;這兩年用過不少的金融數據庫&#xff0c;akshare&#xff0c;baostock&#xff0c;雅虎的&#xff0c;pd自帶的......發現還是Tushare最穩定最好用&…

python打卡day39@浙大疏錦行

知識點回顧 圖像數據的格式&#xff1a;灰度和彩色數據模型的定義顯存占用的4種地方 模型參數梯度參數優化器參數數據批量所占顯存神經元輸出中間狀態 batchisize和訓練的關系 1. 圖像數據格式 - 灰度圖像 &#xff1a;單通道&#xff0c;像素值范圍通常0-255&#xff0c;形狀為…

源碼解析(二):nnUNet

原文 &#x1f600; nnU-Net 是一個用于生物醫學圖像分割的自配置深度學習框架&#xff0c;可自動適應不同的數據集。可用于處理和訓練可能規模龐大的二維和三維醫學圖像。該系統分析數據集屬性并配置優化的基于 U-Net 的分割流程&#xff0c;無需手動參數調整或深度學習專業知…

clickhouse如何查看操作記錄,從日志來查看寫入是否成功

背景 插入表數據后&#xff0c;因為原本表中就有數據&#xff0c;一時間沒想到怎么查看插入是否成功&#xff0c;因為對數據源沒有很多的了解&#xff0c;這時候就想怎么查看下插入是否成功呢&#xff0c;于是就有了以下方法 具體方法 根據操作類型查找&#xff0c;比如inse…

udp 傳輸實時性測量

UDP&#xff08;用戶數據報協議&#xff09;是一種無連接的傳輸協議&#xff0c;適用于實時性要求較高的應用&#xff0c;如視頻流、音頻傳輸和游戲等。測量UDP傳輸的實時性可以通過多種工具和方法實現&#xff0c;以下是一些常見的方法和工具&#xff1a; 1. 使用 iperf 測試…

pikachu通關教程- over permission

如果使用A用戶的權限去操作B用戶的數據&#xff0c;A的權限小于B的權限&#xff0c;如果能夠成功操作&#xff0c;則稱之為越權操作。 越權漏洞形成的原因是后臺使用了 不合理的權限校驗規則導致的。 水平越權 當我們以Lucy賬號登錄&#xff0c;查詢個人信息時&#xff0c;會有…

nc 命令示例

nc -zv 實用示例 示例 1&#xff1a;測試單個 TCP 端口&#xff08;最常見&#xff09; 目標&#xff1a; 檢查主機 webserver.example.com 上的 80 端口 (HTTP) 是否開放。 nc -zv webserver.example.com 80成功輸出&#xff1a; Connection to webserver.example.com (19…

Redis是什么

注&#xff1a;本人不懂Redis是什么&#xff0c;問的大模型&#xff0c;讓它用生動淺顯的語言向我解釋。為了防止忘記&#xff0c;我把它說的記錄下來。接下來的解釋都是大模型生成的&#xff0c;如果有錯誤的地方歡迎指正 。 Redis 是什么&#xff1f;&#xff08;一句話解釋&…

CVE-2021-28164源碼分析與漏洞復現

漏洞概述 漏洞名稱&#xff1a;Jetty 路徑解析邏輯漏洞導致 WEB-INF 敏感信息泄露 漏洞編號&#xff1a;CVE-2021-28164 CVSS 評分&#xff1a;7.5 影響版本&#xff1a;Jetty 9.4.37 - 9.4.38 修復版本&#xff1a;Jetty ≥ 9.4.39 漏洞類型&#xff1a;路徑遍歷/信息泄露 C…

顛覆傳統!單樣本熵最小化如何重塑大語言模型訓練范式?

顛覆傳統&#xff01;單樣本熵最小化如何重塑大語言模型訓練范式&#xff1f; 大語言模型&#xff08;LLM&#xff09;的訓練往往依賴大量標注數據與復雜獎勵設計&#xff0c;但最新研究發現&#xff0c;僅用1條無標注數據和10步優化的熵最小化&#xff08;EM&#xff09;方法…

自動駕駛系統研發系列—激光雷達感知延遲:自動駕駛安全的隱形隱患?

???? 歡迎來到我的技術小筑,一個專為技術探索者打造的交流空間。在這里,我們不僅分享代碼的智慧,還探討技術的深度與廣度。無論您是資深開發者還是技術新手,這里都有一片屬于您的天空。讓我們在知識的海洋中一起航行,共同成長,探索技術的無限可能。 ?? 探索專欄:學…

【MySQL】事務及隔離性

目錄 一、什么是事務 &#xff08;一&#xff09;概念 &#xff08;二&#xff09;事務的四大屬性 &#xff08;三&#xff09;事務的作用 &#xff08;四&#xff09;事務的提交方式 二、事務的啟動、回滾與提交 &#xff08;一&#xff09;事務的啟動、回滾與提交 &am…

視覺分析明火檢測助力山東化工廠火情防控

視覺分析技術賦能化工廠火情防控&#xff1a;從山東事故看明火與煙霧檢測的應用價值 一、背景&#xff1a;山東化工事故中的火情防控痛點 近期&#xff0c;山東高密友道化學有限公司、淄博潤興化工科技有限公司等企業接連發生爆炸事故&#xff0c;暴露出傳統火情防控手段的局…

【小程序】微信小程序備案失敗,有請DeepSeek閃亮出場,看TA如何快速給出解決方案

&#x1f339;歡迎來到《小5講堂》&#x1f339; &#x1f339;這是《小程序》系列文章&#xff0c;每篇文章將以博主理解的角度展開講解。&#x1f339; &#x1f339;溫馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不對之處望指正&#xff01;&a…