设计模式——责任链设计模式(行为型)

news2025/6/5 8:47:02

摘要

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

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 {

    @Override
    protected boolean doHandle(Request request) {
        System.out.println("黑名单校验");
        // 模拟通过
        return true;
    }
}

@Component
public class CreditScoreHandler extends RiskHandler {

    @Override
    protected boolean doHandle(Request request) {
        System.out.println("信用评分校验");
        return true;
    }
}

3.1.3. 构造责任链(可由 Spring 初始化)

@Component
public class RiskChainBuilder {

    @Autowired
    private BlacklistHandler blacklistHandler;
    @Autowired
    private CreditScoreHandler creditScoreHandler;

    @PostConstruct
    public 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 {

    @Autowired
    private 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 {

    @Override
    public boolean handle(LoanRequest request) {
        System.out.println("黑名单校验: " + request.getUserId());
        // 假设用户不在黑名单中
        return true;
    }
}

5.4.2. 🔹 实名认证校验器

@Component
@Order(2)
public class RealNameHandler implements RiskHandler {

    @Override
    public boolean handle(LoanRequest request) {
        System.out.println("实名认证校验: " + request.getName());
        return true;
    }
}

5.4.3. 🔹 信用评分校验器

@Component
@Order(3)
public class CreditScoreHandler implements RiskHandler {

    @Override
    public boolean handle(LoanRequest request) {
        System.out.println("信用评分校验: " + request.getUserId());
        return true;
    }
}

5.4.4. 🔹 反欺诈规则校验器

@Component
@Order(4)
public class AntiFraudHandler implements RiskHandler {

    @Override
    public boolean handle(LoanRequest request) {
        System.out.println("反欺诈校验: " + request.getUserId());
        return true;
    }
}

5.5. 🧩 风控责任链执行器(接口变实现遍历)

@Component
public class RiskCheckExecutor {

    @Autowired
    private 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 {

    @Autowired
    private 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.coloradmin.cn/o/2397130.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Android的医院陪诊预约系统

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;没有什么华丽的语言&#xff0…

基于Spring Boot 电商书城平台系统设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…

【金融基础学习】债券回购方式

债券回购作为货币市场的重要工具&#xff0c;本质上是一种以债券为抵押的短期资金借贷行为。在银行间市场&#xff0c;质押式回购与**买断式回购*是两种主要形式。 1. 质押式回购(Pledged Repo, RP) – 所有权不转移的短期融资工具 1.1 质押式回购概述 质押式回购是交易双方…

第五十九节:性能优化-GPU加速 (CUDA 模块)

在计算机视觉领域,实时性往往是关键瓶颈。当传统CPU处理高分辨率视频流或复杂算法时,力不从心。本文将深入探索OpenCV的CUDA模块,揭示如何通过GPU并行计算实现数量级的性能飞跃。 一、GPU加速:计算机视觉的必由之路 CPU的强项在于复杂逻辑和低延迟任务,但面对图像处理中高…

单元测试-概述入门

目录 main方法测试缺点&#xff1a; 在pom.xm中&#xff0c;引入junit的依赖。,在test/java目录下&#xff0c;创建测试类&#xff0c;并编写对应的测试方法&#xff0c;并在方法上声明test注解。 练习&#xff1a;验证身份证合法性 测试成功 测试失败 main方法测试缺点&am…

⚡ Hyperlane —— 比 Rocket 更快的 Rust Web 框架!

⚡ Hyperlane —— 比 Rocket 更快的 Rust Web 框架&#xff01; 在现代 Web 服务开发中&#xff0c;开发者需要一个既轻量级又高性能的 HTTP 服务器库来简化开发流程&#xff0c;同时确保服务的高效运行。Hyperlane 正是为此而生——一个专为 Rust 开发者设计的 HTTP 服务器库…

《AI Agent项目开发实战》DeepSeek R1模型蒸馏入门实战

一、模型蒸馏环境部署 注&#xff1a;本次实验仍然采用Ubuntu操作系统&#xff0c;基本配置如下&#xff1a; 需要注意的是&#xff0c;本次公开课以Qwen 1.5-instruct模型为例进行蒸馏&#xff0c;从而能省略冷启动SFT过程&#xff0c;并且 由于Qwen系列模型本身性能较强&…

字节golang后端二面

前端接口使用restful格式&#xff0c;post与get的区别是什么&#xff1f; HTTP网络返回的状态码有哪些&#xff1f; go语言切片与数组的区别是什么&#xff1f; MySQL实现并发安全避免两个事务同时对一个记录写操作的手段有哪些&#xff1f; 如何实现业务的幂等性&#xff08;在…

vscode + cmake + ninja+ gcc 搭建MCU开发环境

vscode cmake ninja gcc 搭建MCU开发环境 文章目录 vscode cmake ninja gcc 搭建MCU开发环境1. 前言2. 工具安装及介绍2.1 gcc2.1.1 gcc 介绍2.1.2 gcc 下载及安装 2.2 ninja2.2.1 ninja 介绍2.2 ninja 安装 2.3 cmake2.3.1 cmake 介绍2.3.2 cmake 安装 2.4 VScode 3. 上手…

三种经典算法优化无线传感器网络(WSN)覆盖(SSA-WSN、PSO-WSN、GWO-WSN),MATLAB代码实现

三种经典算法优化无线传感器网络(WSN)覆盖&#xff08;SSA-WSN、PSO-WSN、GWO-WSN&#xff09;&#xff0c;MATLAB代码实现 目录 三种经典算法优化无线传感器网络(WSN)覆盖&#xff08;SSA-WSN、PSO-WSN、GWO-WSN&#xff09;&#xff0c;MATLAB代码实现效果一览基本介绍程序设…

JVM 核心组件深度解析:堆、方法区、执行引擎与本地方法接口

一、JVM 堆内存&#xff1a;对象的生存与消亡之地 作为 Java 虚拟机中最大的内存区域&#xff0c;堆内存是所有对象实例的 “出生地” 与 “安息所”。从程序运行的角度看&#xff0c;所有通过new关键字创建的对象都在堆中分配内存&#xff0c;其生命周期完全由垃圾回收机制&am…

OpenCV4.4.0下载及初步配置(Win11)

目录 OpenCV4.4.0工具下载安装环境变量系统配置 OpenCV4.4.0 工具 系统&#xff1a;Windows 11 下载 OpenCV全版本百度网盘链接&#xff1a;: https://pan.baidu.com/s/15qTzucC6ela3bErdZ285oA?pwdjxuy 提取码: jxuy找到 opencv-4.0.0-vc14_vc15 下载得到 安装 运行op…

使用Mathematica观察多形式根的分布随参数的变化

有两种方式观察多项式的根随着参数变化&#xff1a;&#xff08;1&#xff09;直接制作一个小的动态视频&#xff1b;&#xff08;2&#xff09;绘制所有根形成的痕迹&#xff08;locus&#xff09;。 制作动态视频&#xff1a; (*Arg-plane plotting routine with plotting …

【C++高级主题】转换与多个基类

目录 一、多重继承的虚函数表结构&#xff1a;每个基类一个虚表 1.1 单继承与多重继承的虚表差异 1.2 代码示例&#xff1a;多重继承的虚函数覆盖 1.3 虚表结构示意图 二、指针与引用的类型转换&#xff1a;地址调整的底层逻辑 2.1 派生类指针转基类指针的地址偏移 2.2 …

『uniapp』添加桌面长按快捷操作 shortcuts(详细图文注释)

目录 手机环境适配说明安卓效果图代码 iOS(暂未实测,没有水果开发者)总结 欢迎关注 『uniapp』 专栏&#xff0c;持续更新中 欢迎关注 『uniapp』 专栏&#xff0c;持续更新中 手机环境适配说明 个别手机系统可能需要进行特别的权限设置,否则会无法使用 桌面快捷方式: 已知的有…

【LLM vs Agent】从语言模型到智能体,人工智能迈出的关键一步

目录 一、什么是 LLM&#xff1f;语言的天才&#xff0c;思维的起点 ✅ 特点小结&#xff1a; 二、什么是 Agent&#xff1f;智能的执行者&#xff0c;自主的决策者 ✅ 特点小结&#xff1a; 三、LLM 与 Agent 的关系&#xff1a;是工具&#xff0c;更是大脑 四、案例实战…

麦克风和电脑内播放声音实时识别转文字软件FunASR整合包V5下载

我基于FunASR制作的实时语音识别转文字软件当前更新到V5版本。软件可以实时识别麦克风声音和电脑内播放声音转为文字。 FunASR软件介绍 FunASR 是一款基础语音识别工具包和开源 SOTA 预训练模型&#xff0c;支持语音识别、语音活动检测、文本后处理等。 我使用FunASR制作了一…

PyTorch——卷积层(3)

conv_arithmetic/README.md at master vdumoulin/conv_arithmetic GitHub out_channel1 out_channel2

从 PyTorch 到 TensorFlow Lite:模型训练与推理

一、方案介绍 研发阶段&#xff1a;利用 PyTorch 的动态图特性进行快速原型验证&#xff0c;快速迭代模型设计。 灵活性与易用性&#xff1a;PyTorch 是一个非常灵活且易于使用的深度学习框架&#xff0c;特别适合研究和实验。其动态计算图特性使得模型的构建和调试变得更加直…

【存储基础】存储设备和服务器的关系和区别

文章目录 1. 存储设备和服务器的区别2. 客户端访问数据路径场景1&#xff1a;经过服务器处理场景2&#xff1a;客户端直连 3. 服务器作为"中转站"的作用 刚开始接触存储的时候&#xff0c;以为数据都是存放在服务器上的&#xff0c;服务器和存储设备是一个东西&#…