Java 责任链模式 详解

责任链模式详解

一、责任链模式概述

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许你将请求沿着处理链传递,直到有一个处理者能够处理它为止。这种模式解耦了请求的发送者和接收者,使多个对象都有机会处理请求。

核心特点

  • 解耦请求与处理:发送者不需要知道具体由哪个处理者处理请求
  • 动态组合:可以动态地改变处理链
  • 灵活性:可以灵活地新增或修改处理流程
  • 多重处理:一个请求可以被多个处理者处理

二、责任链模式的结构

主要角色

  1. Handler:抽象处理者,定义处理请求的接口
  2. ConcreteHandler:具体处理者,实现处理逻辑
  3. Client:客户端,创建处理链并提交请求

三、责任链模式的实现

1. 基本实现

// 抽象处理者
public abstract class Handler {protected Handler successor;public void setSuccessor(Handler successor) {this.successor = successor;}public abstract void handleRequest(Request request);
}// 具体处理者A
public class ConcreteHandlerA extends Handler {public void handleRequest(Request request) {if (request.getType().equals("TypeA")) {System.out.println("HandlerA处理请求: " + request.getContent());} else if (successor != null) {successor.handleRequest(request);}}
}// 具体处理者B
public class ConcreteHandlerB extends Handler {public void handleRequest(Request request) {if (request.getType().equals("TypeB")) {System.out.println("HandlerB处理请求: " + request.getContent());} else if (successor != null) {successor.handleRequest(request);}}
}// 请求对象
public class Request {private String type;private String content;public Request(String type, String content) {this.type = type;this.content = content;}// getter方法public String getType() { return type; }public String getContent() { return content; }
}// 使用示例
Handler h1 = new ConcreteHandlerA();
Handler h2 = new ConcreteHandlerB();
h1.setSuccessor(h2);Request request = new Request("TypeB", "测试请求");
h1.handleRequest(request);

2. 更灵活的实现(带中断)

public interface Handler {boolean handle(Request request);
}public class AuthHandler implements Handler {public boolean handle(Request request) {if (!request.isAuthenticated()) {System.out.println("认证失败");return false;}System.out.println("认证通过");return true;}
}public class LoggingHandler implements Handler {public boolean handle(Request request) {System.out.println("记录请求日志: " + request);return true;}
}public class ProcessingHandler implements Handler {public boolean handle(Request request) {System.out.println("处理业务请求: " + request);return true;}
}public class HandlerChain {private List<Handler> handlers = new ArrayList<>();public HandlerChain addHandler(Handler handler) {handlers.add(handler);return this;}public boolean process(Request request) {for (Handler handler : handlers) {if (!handler.handle(request)) {return false;}}return true;}
}// 使用示例
HandlerChain chain = new HandlerChain().addHandler(new AuthHandler()).addHandler(new LoggingHandler()).addHandler(new ProcessingHandler());Request request = new Request("test");
chain.process(request);

四、责任链模式的应用场景

1. Web请求过滤器

public interface Filter {void doFilter(HttpRequest request, HttpResponse response, FilterChain chain);
}public class AuthenticationFilter implements Filter {public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) {if (!request.isAuthenticated()) {response.setStatus(401);return;}System.out.println("认证通过");chain.doFilter(request, response);}
}public class LoggingFilter implements Filter {public void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) {System.out.println("请求日志: " + request.getPath());chain.doFilter(request, response);}
}public class FilterChain {private List<Filter> filters = new ArrayList<>();private int index = 0;public FilterChain addFilter(Filter filter) {filters.add(filter);return this;}public void doFilter(HttpRequest request, HttpResponse response) {if (index < filters.size()) {Filter filter = filters.get(index++);filter.doFilter(request, response, this);}}
}

2. 审批流程系统

public abstract class Approver {protected Approver successor;protected String name;public Approver(String name) {this.name = name;}public void setSuccessor(Approver successor) {this.successor = successor;}public abstract void processRequest(PurchaseRequest request);
}public class DepartmentHead extends Approver {public DepartmentHead(String name) {super(name);}public void processRequest(PurchaseRequest request) {if (request.getAmount() < 5000) {System.out.println("部门主管" + name + "审批采购单: " + request);} else if (successor != null) {successor.processRequest(request);}}
}public class VicePresident extends Approver {public VicePresident(String name) {super(name);}public void processRequest(PurchaseRequest request) {if (request.getAmount() < 10000) {System.out.println("副总裁" + name + "审批采购单: " + request);} else if (successor != null) {successor.processRequest(request);}}
}// 使用示例
Approver zhangsan = new DepartmentHead("张三");
Approver lisi = new VicePresident("李四");
zhangsan.setSuccessor(lisi);PurchaseRequest request = new PurchaseRequest(8000, "购买设备");
zhangsan.processRequest(request);

3. 异常处理系统

public interface ExceptionHandler {void handle(Exception e, ExceptionHandlerChain chain);
}public class NullPointerHandler implements ExceptionHandler {public void handle(Exception e, ExceptionHandlerChain chain) {if (e instanceof NullPointerException) {System.out.println("处理空指针异常");} else {chain.handle(e);}}
}public class IOExceptionHandler implements ExceptionHandler {public void handle(Exception e, ExceptionHandlerChain chain) {if (e instanceof IOException) {System.out.println("处理IO异常");} else {chain.handle(e);}}
}public class DefaultExceptionHandler implements ExceptionHandler {public void handle(Exception e, ExceptionHandlerChain chain) {System.out.println("默认异常处理");}
}public class ExceptionHandlerChain {private List<ExceptionHandler> handlers = new ArrayList<>();private int index = 0;public ExceptionHandlerChain addHandler(ExceptionHandler handler) {handlers.add(handler);return this;}public void handle(Exception e) {if (index < handlers.size()) {ExceptionHandler handler = handlers.get(index++);handler.handle(e, this);}}
}

五、责任链模式的变体

1. 功能链模式

public interface Function<T, R> {R apply(T t, Function<T, R> next);
}public class FunctionChain<T, R> {private List<Function<T, R>> functions = new ArrayList<>();public FunctionChain<T, R> addFunction(Function<T, R> function) {functions.add(function);return this;}public R execute(T input) {if (functions.isEmpty()) return null;Function<T, R> first = functions.get(0);return first.apply(input, (t, n) -> {int nextIndex = functions.indexOf(n) + 1;if (nextIndex < functions.size()) {return functions.get(nextIndex).apply(t, functions.get(nextIndex));}return null;});}
}

2. 中断式责任链

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

六、责任链模式的优缺点

优点

  1. 降低耦合度:请求发送者与接收者解耦
  2. 增强灵活性:可以动态调整处理链
  3. 简化对象:每个处理者只需关注自己的责任范围
  4. 易于扩展:新增处理者不影响现有代码

缺点

  1. 请求可能未被处理:如果没有处理者能处理请求
  2. 性能影响:较长的处理链可能影响性能
  3. 调试困难:请求的传递过程可能不易追踪

七、最佳实践

  1. 明确处理范围:每个处理者应明确自己的处理范围
  2. 控制链的长度:避免过长的处理链影响性能
  3. 提供默认处理:确保请求最终能被处理
  4. 日志记录:记录请求在链中的传递过程
  5. 考虑中断机制:允许在处理过程中中断传递

八、总结

责任链模式是处理复杂流程的有效方案,特别适用于:

  • 有多个对象可以处理同一请求
  • 需要动态指定处理流程
  • 需要解耦请求发送者和接收者
  • 处理流程可能变化的情况

在实际开发中,责任链模式常见于:

  • Web框架的过滤器链
  • 审批工作流系统
  • 异常处理系统
  • 事件处理管道
  • 中间件设计

正确使用责任链模式可以提高系统的灵活性和可扩展性,但需要注意控制处理链的复杂度,避免性能问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/76384.shtml

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

相关文章

【C++初阶】--- string类

1.STL简介 STL(standard template libaray-标准模板库)&#xff1a;是C标准库的重要组成部分&#xff0c;不仅是一个可复用的组件库&#xff0c;而且是一个包罗数据结构与算法的软件框架。 2.string类 2.1什么是string类 std::string 类是 C 标准库中用于处理和操作字符串…

Ubuntu 20.04 中 Git 的安装、配置和基本操作指南

本文为经验 所谈 使用版本为ubuntu20.04 1 ubuntu的git初始化 1.安装git sudo apt-get install git 可通过git --version 命令查看&#xff0c;正常输出git版本号即安装成功。 2.配置用户名和邮箱名 git config --global user.name "Your Name" git config --globa…

conda 激活环境vscode的Bash窗口

多份conda环境注意事项&#xff0c;当时安装了两个conda环境&#xff0c;miniconda和conda&#xff0c;导致环境总是冲突矛盾。初始化时需要更加注意。 $ C:/Users/a_hal/miniconda3/Scripts/conda.exe init bash能够显示用哪里的conda环境命令执行。 然后直接conda activate…

Mac下小智AI本地环境部署

可以进行聊天、编写程序、播放歌曲等等的小智语音聊天小助手&#xff0c;在Mac环境下修改源代码&#xff0c;值得拥有。本篇内容主要讲解Mac下环境的搭建&#xff0c;WebSocket的修改。注&#xff1a;环境python3.12.0、ESP-IDF5.4.0、开发板ESP32S3。 目录 1.Git安装2.Python…

Linux安装Cmake (Centos 7.9)

cmake安装 这个虽然已经更新到了4.0.0版本了&#xff0c;但是我们要用3.5版本的&#xff0c;因为这个比较稳定 官方地址&#xff1a;https://github.com/Kitware/CMake/releases/tag/v3.5.0&#xff0c;选择那个cmake-3.5.0-Linux-x86_64.tar.gz下载&#xff0c; 首先解压文…

基于 SpringBoot 的旧物置换网站

收藏关注不迷路&#xff01;&#xff01; &#x1f31f;文末获取源码数据库&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff08;免费咨询指导选题&#xff09;&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;希望帮助更多…

ELK 通过 logstash 收集单个/多个日志文件

一、收集单个日志文件 注意事项&#xff1a; logstah 服务默认启动用户和组是 logstash被收集的日志文件有读的权限并对写入的文件有写权限而 logstash 是普通用户 1.1 编辑 logstash 配置文件 vim /etc/logstash/conf.d/test.conf input {file {path > "/var/log/…

分享一个Drools规则引擎微服务Docker部署

通常我们都是把Drools作为嵌入式使用&#xff0c;但在微服务泛滥时代&#xff0c;还在老套的嵌入式显然不符合微服务架构要求&#xff0c;本文分享一个把Drools作为微服务独立部署的方案。 本方案基于Drools引擎微服务&#xff0c;提供REST接口。 1、可以动态部署Drools规则2…

Mac 本地化部署 dify

Macbook 本地化部署 dify 目录 Macbook 本地化部署 dify安装dockerdocker下载地址 安装dify下载dify到本地github可能遇到的问题: github打开超时在本地解压dify.zip文件本地化部署docker部署可能遇到的问题: 部署超时登录体验 dify 安装docker docker下载地址 根据电脑芯片选…

串口中断接收与环形缓冲实例(apollo3 blue plus)

#define DEV_UART1 1 #define GPS_POWER_PIN 13 #define GPS_LOG_ENABLE 1 #define MAX_UART1_SIZE 1024 #define AM_BSP_GPIO_COM_UART1_TX 8 #define AM_BSP_GPIO_COM_UART1_RX 9 // 定义环形缓冲区结构 typed…

操作系统高频(五)linux命令

操作系统高频&#xff08;五&#xff09;linux命令 1.Linux中查看进程运行状态的指令、tar解压文件的参数。⭐⭐⭐ 在Linux中&#xff0c;可以使用以下指令查看进程的运行状态&#xff1a; top&#xff1a; 用于实时监视系统的进程活动和系统资源使用情况。在终端中运行top…

Spring Boot 快速入手

前言&#xff1a;为什么选择 Spring Boot&#xff1f; &#x1f680; 在现代 Java 开发中&#xff0c;Spring Boot 已成为最流行的后端框架之一。无论是小型 Web 应用、企业级系统&#xff0c;还是微服务架构&#xff0c;Spring Boot 都能提供快速开发、自动配置、轻量级部署的…

oracle-blob导出,在ob导入失败

导出&#xff1a; [oraclelncs dmp]$ /home/oracle/sqluldr2 gistar/res#pwd192.168.205.58:1521/lndb query"select * from an_odn_picture where length(PIC_CONTENT)<25000" filean_odn_picture.csv Charsetutf8 textCSV 0 rows exported at 2025-…

RK3568 pinctrl内容讲解

文章目录 一、pinctrl的概念`pinctrl` 的作用设备树中的 `pinctrl` 节点典型的 `pinctrl` 节点结构例子`pinctrl` 的重要性总结二、RK3568的pinctrl讲解1. `pinctrl` 节点2. `gpio0` 至 `gpio4` 子节点每个 `gpioX` 子节点的结构和作用3. `gpio1` 到 `gpio4` 子节点总结1. `aco…

北京南文观点:后糖酒会营销,以战略传播重构品牌信心坐标

第112届全国糖酒会落下帷幕&#xff0c;参展品牌面临一个关键命题。如何在流量洪流中沉淀品牌价值&#xff1f;北京南文&#xff08;全称&#xff1a;南文乐园科技文化&#xff08;北京&#xff09;有限公司&#xff09;认为&#xff0c;糖酒会的结束恰是算法时代品牌认知战的真…

html5时钟升级!支持切换深浅模式 Canvas实现现代化动态时钟

HTML5 Canvas实现现代化动态时钟 这里写目录标题 HTML5 Canvas实现现代化动态时钟项目介绍技术实现1. 项目架构2. Canvas绘图实现2.1 表盘绘制2.2 刻度绘制2.3 指针绘制 3. 动画效果4. 主题切换 项目亮点技术要点总结项目收获改进方向结语 项目介绍 本项目使用HTML5 Canvas技术…

《SRv6 网络编程:开启IP网络新时代》第2章、第3章:SRv6基本原理和基础协议

背景 根据工作要求、本人掌握的知识情况&#xff0c;仅针对《SRv6 网络编程&#xff1a;开启IP网络新时代》书籍中涉及的部分知识点进行总结梳理&#xff0c;并与工作小组进行分享&#xff0c;不涉及对原作的逐字搬运。 问题 组内同事提出的问题&#xff1a;本文缺扩展头描述…

卫星电话究竟是“锦上添花”?还是“刚需之选”?

在万物互联的时代浪潮中&#xff0c;卫星电话究竟是可有可无的“锦上添花”&#xff0c;还是至关重要的“刚需之选”&#xff1f;随着通信技术的持续进步与应用场景的日益拓展&#xff0c;这一问题的答案正逐渐明晰。 在5G基站覆盖99%行政村的今天&#xff0c;人类依然要直面自…

C语言复习笔记--指针(1)

今天我们进入指针的复习了.这部分有很多知识,话不多说,让我们进入指针的世界吧. 内存和地址 要想学指针就不能不学内存和地址. 内存 其中&#xff0c;每个内存单元&#xff0c;相当于⼀个学⽣宿舍&#xff0c;⼀ 个字节空间⾥⾯能放8个⽐特位&#xff0c;就好⽐同学们 住的⼋⼈…

【蓝桥杯每日一题】4.1

&#x1f3dd;️专栏&#xff1a; 【蓝桥杯备篇】 &#x1f305;主页&#xff1a; f狐o狸x "今日秃头刷题&#xff0c;明日荣耀加冕&#xff01;" 今天我们来练习二分算法 不熟悉二分算法的朋友可以看&#xff1a;【C语言刷怪篇】二分法_编程解决算术问题-CSDN博客 …