摘要

责任链设计模式是一种行为型设计模式,旨在将请求的发送者与接收者解耦,通过多个处理器对象按链式结构依次处理请求,直到某个处理器处理为止。它包含抽象处理者、具体处理者和客户端等核心角色。该模式适用于多个对象可能处理请求的场景,如风控系统中的贷款申请流程,通过链式组合处理整个流程。实现方式包括链式引用和集合遍历等,适用于信贷申请风控校验等实际应用。

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…