当前位置: 首页 > news >正文

责任链设计模式详解

责任链设计模式详解

一、责任链模式概述

责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许你将请求沿着处理链传递,直到有一个处理者处理它。这种模式让多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。

核心概念

  • 处理者:定义处理请求的接口
  • 具体处理者:实现处理请求的具体逻辑
  • :将处理者连接起来,形成处理链

二、责任链模式的结构

2.1 UML 类图

┌─────────────┐    ┌─────────────────┐
│   Client    │    │   Handler       │
│             │    │                 │
│ +main()     │    │ +handleRequest()│
└─────────────┘    │ +setNext()      ││           └─────────────────┘│                     △│                     ││           ┌─────────────────┐└───────────│ ConcreteHandler ││                 ││ +handleRequest()│└─────────────────┘

2.2 核心角色

  1. Handler(抽象处理者):定义处理请求的接口
  2. ConcreteHandler(具体处理者):实现具体的处理逻辑
  3. Client(客户端):创建处理链并向链头发送请求

三、责任链模式的实现

3.1 基础实现

步骤1:定义抽象处理者
/*** 抽象处理者 - 审批人*/
public abstract class Approver {protected Approver nextApprover;  // 下一个处理者protected String name;            // 处理者名称public Approver(String name) {this.name = name;}// 设置下一个处理者public Approver setNext(Approver nextApprover) {this.nextApprover = nextApprover;return this.nextApprover;  // 返回下一个处理者,支持链式调用}// 处理审批请求的抽象方法public abstract void processRequest(PurchaseRequest request);
}
步骤2:定义请求对象
/*** 采购请求 - 请求对象*/
public class PurchaseRequest {private int type;        // 请求类型private int number;      // 请求编号private float price;     // 金额private String purpose;  // 用途public PurchaseRequest(int type, int number, float price, String purpose) {this.type = type;this.number = number;this.price = price;this.purpose = purpose;}// getter 方法public int getType() { return type; }public int getNumber() { return number; }public float getPrice() { return price; }public String getPurpose() { return purpose; }
}
步骤3:实现具体处理者
/*** 具体处理者 - 部门经理*/
public class DepartmentManager extends Approver {public DepartmentManager(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest request) {if (request.getPrice() <= 5000) {// 部门经理可以审批5000元以下的采购System.out.println("请求编号: " + request.getNumber() + ",金额: " + request.getPrice() + ",目的: " + request.getPurpose());System.out.println("审批人: " + this.name + " [部门经理]");} else if (nextApprover != null) {// 超过权限,传递给下一个处理者System.out.println("部门经理 " + name + " 无权审批,转交上级...");nextApprover.processRequest(request);} else {// 没有下一个处理者,审批失败System.out.println("请求无法处理,审批链结束");}}
}/*** 具体处理者 - 副总经理*/
public class ViceGeneralManager extends Approver {public ViceGeneralManager(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest request) {if (request.getPrice() <= 10000) {// 副总经理可以审批10000元以下的采购System.out.println("请求编号: " + request.getNumber() + ",金额: " + request.getPrice() + ",目的: " + request.getPurpose());System.out.println("审批人: " + this.name + " [副总经理]");} else if (nextApprover != null) {// 超过权限,传递给下一个处理者System.out.println("副总经理 " + name + " 无权审批,转交上级...");nextApprover.processRequest(request);} else {System.out.println("请求无法处理,审批链结束");}}
}/*** 具体处理者 - 总经理*/
public class GeneralManager extends Approver {public GeneralManager(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest request) {if (request.getPrice() <= 50000) {// 总经理可以审批50000元以下的采购System.out.println("请求编号: " + request.getNumber() + ",金额: " + request.getPrice() + ",目的: " + request.getPurpose());System.out.println("审批人: " + this.name + " [总经理]");} else {// 超过总经理权限,需要董事会审批System.out.println("金额过大(" + request.getPrice() + "),需要召开董事会讨论");}}
}
步骤4:客户端使用
/*** 客户端 - 测试责任链模式*/
public class ChainOfResponsibilityClient {public static void main(String[] args) {// 1. 创建处理者Approver departmentManager = new DepartmentManager("张经理");Approver viceManager = new ViceGeneralManager("李副总");Approver generalManager = new GeneralManager("王总经理");// 2. 构建责任链:部门经理 -> 副总经理 -> 总经理departmentManager.setNext(viceManager).setNext(generalManager);// 3. 创建不同的采购请求System.out.println("=== 测试责任链模式 ===");// 请求1:3000元,应该由部门经理审批PurchaseRequest request1 = new PurchaseRequest(1, 1001, 3000, "购买办公用品");System.out.println("\n请求1: 3000元采购");departmentManager.processRequest(request1);// 请求2:8000元,应该由副总经理审批PurchaseRequest request2 = new PurchaseRequest(2, 1002, 8000, "部门团队建设");System.out.println("\n请求2: 8000元采购");departmentManager.processRequest(request2);// 请求3:30000元,应该由总经理审批PurchaseRequest request3 = new PurchaseRequest(3, 1003, 30000, "购买服务器");System.out.println("\n请求3: 30000元采购");departmentManager.processRequest(request3);// 请求4:100000元,超过审批权限PurchaseRequest request4 = new PurchaseRequest(4, 1004, 100000, "公司车辆采购");System.out.println("\n请求4: 100000元采购");departmentManager.processRequest(request4);}
}

3.2 输出结果

=== 测试责任链模式 ===请求1: 3000元采购
请求编号: 1001,金额: 3000.0,目的: 购买办公用品
审批人: 张经理 [部门经理]请求2: 8000元采购
部门经理 张经理 无权审批,转交上级...
请求编号: 1002,金额: 8000.0,目的: 部门团队建设
审批人: 李副总 [副总经理]请求3: 30000元采购
部门经理 张经理 无权审批,转交上级...
副总经理 李副总 无权审批,转交上级...
请求编号: 1003,金额: 30000.0,目的: 购买服务器
审批人: 王总经理 [总经理]请求4: 100000元采购
部门经理 张经理 无权审批,转交上级...
副总经理 李副总 无权审批,转交上级...
金额过大(100000.0),需要召开董事会讨论

四、责任链模式的进阶实现

4.1 使用集合管理处理链

import java.util.ArrayList;
import java.util.List;/*** 处理链管理器*/
public class ApprovalChain {private List<Approver> approvers = new ArrayList<>();private int index = 0;  // 当前处理者索引// 添加处理者public void addApprover(Approver approver) {approvers.add(approver);}// 处理请求public void processRequest(PurchaseRequest request) {if (index < approvers.size()) {Approver currentApprover = approvers.get(index);index++;currentApprover.processRequest(request);} else {System.out.println("所有处理者都无法处理该请求");}}// 重置链(支持重复使用)public void reset() {index = 0;}
}/*** 修改后的具体处理者(简化版)*/
public class SimpleApprover extends Approver {private double maxAmount;public SimpleApprover(String name, double maxAmount) {super(name);this.maxAmount = maxAmount;}@Overridepublic void processRequest(PurchaseRequest request) {if (request.getPrice() <= maxAmount) {System.out.println("审批通过: " + name + " 审批了 " + request.getPrice() + "元");} else if (nextApprover != null) {System.out.println(name + " 无法审批,转交下一级");nextApprover.processRequest(request);} else {System.out.println("无人能够审批该请求");}}
}// 使用示例
public class AdvancedChainExample {public static void main(String[] args) {// 创建处理链管理器ApprovalChain chain = new ApprovalChain();chain.addApprover(new SimpleApprover("经理", 5000));chain.addApprover(new SimpleApprover("总监", 20000));chain.addApprover(new SimpleApprover("总经理", 100000));// 处理多个请求PurchaseRequest[] requests = {new PurchaseRequest(1, 1001, 3000, "测试1"),new PurchaseRequest(2, 1002, 15000, "测试2"),new PurchaseRequest(3, 1003, 50000, "测试3"),new PurchaseRequest(4, 1004, 200000, "测试4")};for (PurchaseRequest request : requests) {System.out.println("\n处理请求: " + request.getPrice() + "元");chain.processRequest(request);chain.reset();  // 重置链以处理下一个请求}}
}

4.2 支持中断的责任链

/*** 支持中断的抽象处理者*/
public abstract class InterruptibleApprover {protected InterruptibleApprover nextApprover;public void setNext(InterruptibleApprover nextApprover) {this.nextApprover = nextApprover;}/*** 处理请求,返回true表示继续传递,false表示中断链*/public abstract boolean processRequest(PurchaseRequest request);
}/*** 具体处理者 - 支持中断*/
public class InterruptibleDepartmentManager extends InterruptibleApprover {private String name;public InterruptibleDepartmentManager(String name) {this.name = name;}@Overridepublic boolean processRequest(PurchaseRequest request) {if (request.getPrice() <= 5000) {System.out.println(name + " 审批了 " + request.getPrice() + "元");return false;  // 审批完成,中断链} else if (request.getPurpose().contains("紧急")) {System.out.println(name + " 处理紧急请求: " + request.getPurpose());// 紧急请求需要所有领导知晓,但不中断链return true;} else {System.out.println(name + " 无法审批,转交上级");return true;  // 继续传递}}
}

五、责任链模式在真实项目中的应用

5.1 Java Web 中的 Filter 链

// 模拟Servlet Filter的责任链实现
public interface Filter {void doFilter(ServletRequest request, ServletResponse response, FilterChain chain);
}public class FilterChain {private List<Filter> filters = new ArrayList<>();private int index = 0;public void addFilter(Filter filter) {filters.add(filter);}public void doFilter(ServletRequest request, ServletResponse response) {if (index < filters.size()) {Filter filter = filters.get(index);index++;filter.doFilter(request, response, this);}// 链执行完毕,执行实际业务逻辑}
}// 具体过滤器
public class LoggingFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {System.out.println("日志记录: " + new Date());chain.doFilter(request, response);  // 继续下一个过滤器System.out.println("日志记录完成");}
}public class AuthFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {if (isAuthenticated(request)) {chain.doFilter(request, response);} else {// 认证失败,中断链System.out.println("认证失败");}}private boolean isAuthenticated(ServletRequest request) {// 认证逻辑return true;}
}

5.2 事件处理系统

/*** 事件处理器链*/
public class EventHandlerChain {private List<EventHandler> handlers = new ArrayList<>();public void addHandler(EventHandler handler) {handlers.add(handler);}public boolean handleEvent(Event event) {for (EventHandler handler : handlers) {if (handler.canHandle(event)) {handler.handle(event);return true;  // 事件已处理}}return false;  // 没有处理器能处理该事件}
}public interface EventHandler {boolean canHandle(Event event);void handle(Event event);
}

六、责任链模式的优缺点

优点:

  1. 降低耦合度:请求发送者不需要知道哪个对象会处理它的请求
  2. 增强灵活性:可以动态地增加或修改处理链
  3. 简化对象:每个处理者只需关注自己的责任范围
  4. 符合开闭原则:新增处理者无需修改现有代码

缺点:

  1. 请求可能未被处理:如果链中没有合适的处理者,请求可能得不到处理
  2. 性能影响:长链可能影响性能,特别是在链的遍历上
  3. 调试困难:请求的传递路径可能不直观,调试较复杂

七、适用场景

  1. 多级审批系统:如采购审批、请假审批等
  2. 事件处理系统:如GUI事件处理、异常处理
  3. 过滤器/拦截器链:如Web应用中的Filter、Interceptor
  4. 日志处理系统:不同级别的日志由不同处理器处理
  5. 数据验证链:多个验证规则依次执行

八、总结

责任链模式通过将请求的发送者和接收者解耦,提供了灵活的请求处理机制。在实际开发中,它特别适合于需要多级处理或动态处理流程的场景。

关键要点

  • 合理设计处理者的职责范围
  • 注意处理链的长度,避免性能问题
  • 考虑请求可能未被处理的情况
  • 支持动态调整处理链的顺序和内容

通过合理运用责任链模式,可以构建出灵活、可扩展的处理系统,大大提高代码的可维护性和可扩展性。

http://www.dtcms.com/a/404018.html

相关文章:

  • 学习2025.9.24
  • 视频 播放网站怎么做黄石企业网站建设
  • C#图像处理五大核心误区与解决方案‌
  • 珠海做网站公司哪家好国家住房与城乡建设部网站
  • 织梦做网站要多长时间免费那个网站
  • 新桥网站建设济南小程序网站制作
  • 一文读懂循环神经网络(RNN):原理、局限与LSTM解决方案
  • 以绿色为主的网站wordpress 单 中
  • Linux 企业级备份体系实战:cron/anacron/restic/rclone 对比与脚本总结
  • 做的网站太大怎么办神华科技 网站建设
  • 软件公司 网站建设费分录如何创建网站主页
  • 北京城乡和住房建设部网站济源新站seo关键词排名推广
  • 网站页脚的制作西部数码上传网站
  • 素材网站下载网店设计与装修
  • 《2025年AI产业发展十大趋势报告》六十七
  • 花生壳做网站需要备案西安制作标书的公司
  • 笔记本copilot按键映射为右Ctrl键的方法
  • 网站建设与维护高职网易企业邮箱登入路口
  • 廊坊网站建设制作制作企业网站html
  • JavaScript——DOM补充
  • ICPC Central Russia Regional Contest, 2024 补题
  • 【系统架构设计(36)】网络规划与设计
  • SQL 注入风险与解决方案实战解析
  • 企业如何做网站推广出名的包装设计
  • 【STM32】位带操作
  • 供需网站开发做网站怎么发布
  • 保定网站建设方法水墨画风格网站
  • LINUX嵌入式面经(六)--常见算法篇
  • 网站优化推广方法庐江住房建设局网站
  • C语言基础【24】:组包和解包