责任链模式_行为型_GOF23

news/2025/4/2 6:31:08/

责任链模式

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,核心思想是将多个处理请求的对象连成一条链,请求沿链传递直到被处理。它像现实中的“多级审批流程”——请假或报销时,申请会逐级提交给不同权限的领导,直到有人能处理为止。


一、通俗理解

假设你开发一个多级审批系统:

  1. 传统方式:用大量 if-else 判断不同金额的报销单由谁审批,代码臃肿且难以扩展。
  2. 责任链模式
    • 抽象审批人:定义统一的处理接口,并持有下一级审批人的引用。
    • 具体审批人(如组长、经理、CEO):各自处理权限内的请求,超出权限则转交下一级。
      最终只需将审批人连成链,客户端提交请求到链头,无需关心具体处理细节。

二、模式结构
  1. 抽象处理者(Handler):定义处理请求的接口,包含设置下一处理者的方法(如 setNext())。
  2. 具体处理者(ConcreteHandler):实现处理逻辑,若无法处理则转交下一级。
  3. 客户端(Client):创建处理链,发起请求。

三、适用场景
  1. 多级审批流程:如请假、报销、工单处理。
  2. 动态扩展处理逻辑:如日志过滤器、权限验证链。
  3. 请求发送者与接收者解耦:如 GUI 事件传递、网络请求拦截器。

四、代码实现
1. C++ 示例(报销审批链)
#include <iostream>  // 抽象处理者  
class Approver {  
protected:  Approver* next = nullptr;  
public:  void setNext(Approver* nextApprover) {  next = nextApprover;  }  virtual void handle(int amount) = 0;  
};  // 具体处理者:组长  
class GroupLeader : public Approver {  
public:  void handle(int amount) override {  if (amount <= 1000) {  std::cout << "组长审批通过(金额:" << amount << "元)" << std::endl;  } else if (next) {  next->handle(amount);  } else {  std::cout << "无人能处理此金额!" << std::endl;  }  }  
};  // 具体处理者:经理  
class Manager : public Approver {  
public:  void handle(int amount) override {  if (amount <= 5000) {  std::cout << "经理审批通过(金额:" << amount << "元)" << std::endl;  } else if (next) {  next->handle(amount);  }  }  
};  int main() {  GroupLeader leader;  Manager manager;  leader.setNext(&manager);  leader.handle(800);     // 组长处理  leader.handle(3000);    // 经理处理  leader.handle(10000);   // 无处理  return 0;  
}  

输出

组长审批通过(金额:800元)  
经理审批通过(金额:3000元)  
无人能处理此金额!  

解析

  • 组长处理 ≤1000 元的请求,否则转交经理。
  • 经理处理 ≤5000 元的请求,更高金额无后续处理者。

2. Python 示例(日志过滤器链)
from abc import ABC, abstractmethod  class LogHandler(ABC):  def __init__(self):  self.next = None  def set_next(self, next_handler):  self.next = next_handler  @abstractmethod  def handle(self, log_level, message):  pass  class DebugHandler(LogHandler):  def handle(self, log_level, message):  if log_level == "DEBUG":  print(f"[DEBUG] {message}")  elif self.next:  self.next.handle(log_level, message)  class ErrorHandler(LogHandler):  def handle(self, log_level, message):  if log_level == "ERROR":  print(f"[ERROR] {message}")  elif self.next:  self.next.handle(log_level, message)  # 客户端  
debug = DebugHandler()  
error = ErrorHandler()  
debug.set_next(error)  debug.handle("DEBUG", "调试信息")  # [DEBUG] 调试信息  
debug.handle("ERROR", "系统崩溃")  # [ERROR] 系统崩溃  
debug.handle("INFO", "普通日志")   # 无输出  

解析

  • DebugHandler 处理 DEBUG 日志,其他级别转交下一处理者。
  • 链式调用避免硬编码日志级别判断。

3. Java 示例(请假审批系统)
// 抽象处理者  
abstract class Approver {  protected Approver next;  public void setNext(Approver next) {  this.next = next;  }  public abstract void handle(int days);  
}  // 具体处理者:组长  
class GroupLeader extends Approver {  @Override  public void handle(int days) {  if (days <= 3) {  System.out.println("组长批准请假 " + days + "天");  } else if (next != null) {  next.handle(days);  }  }  
}  // 具体处理者:经理  
class Manager extends Approver {  @Override  public void handle(int days) {  if (days <= 7) {  System.out.println("经理批准请假 " + days + "天");  } else if (next != null) {  next.handle(days);  }  }  
}  public class Client {  public static void main(String[] args) {  GroupLeader leader = new GroupLeader();  Manager manager = new Manager();  leader.setNext(manager);  leader.handle(2);  // 组长处理  leader.handle(5);  // 经理处理  leader.handle(10); // 无处理  }  
}  

输出

组长批准请假 2天  
经理批准请假 5天  

解析

  • 组长处理 ≤3 天的请假,其余转交经理。
  • 责任链动态组合,新增审批人只需扩展链。

五、优缺点分析
优点缺点
1. 解耦请求与处理逻辑:客户端无需知道具体处理者1. 性能问题:长链可能导致请求传递慢
2. 灵活扩展:动态增减处理节点,符合开闭原则2. 调试困难:请求可能未被处理或循环传递
3. 单一职责:每个处理者专注自身逻辑3. 链配置错误风险:需确保链正确连接

六、总结

责任链模式通过链式传递请求,实现了处理逻辑的动态组合与解耦。适用于多级审批、日志过滤等场景,但需注意链长控制和错误处理。其核心价值在于:

  1. 灵活扩展:新增处理者无需修改原有代码。
  2. 职责分离:每个处理者只关注自身任务。
  3. 实际应用:如 Spring MVC 的拦截器链、Netty 的 ChannelPipeline。

http://www.ppmy.cn/news/1584564.html

相关文章

通过 Docker Swarm 集群探究 Overlay 网络跨主机通信原理

什么是Overlay网络, 用于解决什么问题 ? Overlay网络通过在现有网络之上创建一个虚拟网络层, 解决不同主机的容器之间相互通信的问题 如果没有Overlay网络&#xff0c;实现跨主机的容器通信通常需要以下方法&#xff1a; 端口映射使用宿主机网络模式 这些方法牺牲了容器网络…

Turnitin系统查重,论文会被收录吗?

Turnitin系统目前是可以检测语言范围最广的论文检测系统&#xff0c;还可以检测小语种论文。 Turnitin是世界上主流的学术不端检测系统之一&#xff0c;它的系统与国际著名出版商&#xff08;收录90%以上的SCI期刊&#xff09;指定使用的CrossCheck反剽窃检测系统的技术支持、…

项目-苍穹外卖(十三) 地址模块(导入)+用户下单

一、地址模块 需求分析和设计: 新增地址&#xff1a; Controller: /*** 新增地址** param addressBook* return*/PostMappingApiOperation("新增地址")public Result save(RequestBody AddressBook addressBook) {addressBookService.save(addressBook);return Resu…

Playwright从入门到实战:比Selenium更快的数据爬取案例实战

摘要 Playwright 是微软开源的下一代浏览器自动化工具&#xff0c;凭借其高性能、跨浏览器支持和现代化设计&#xff0c;迅速成为 Web 自动化领域的热门选择。本文将从 安装配置 开始&#xff0c;通过 实战演练 展示其核心功能&#xff0c;并与 Selenium 深度对比&#xff0c;…

漏洞挖掘---灵当CRM客户管理系统getOrderList SQL注入漏洞

一、灵当CRM 灵当CRM是上海灵当信息科技有限公司旗下产品&#xff0c;适用于中小型企业。它功能丰富&#xff0c;涵盖销售、服务、财务等管理功能&#xff0c;具有性价比高、简洁易用、可定制、部署灵活等特点&#xff0c;能助力企业提升经营效益和客户满意度。 二、FOFA-Sear…

java替换html中的标签

实现方法 通过正则表达式统一替换&#xff1a;<[^>]> 实现过程 import retext <!DOCTYPE html> <html> <head><title>示例页面</title> </head> <body><h1>欢迎来到示例页面</h1><p>这是一个段落。<…

第三届全国技能大赛广西选拔赛 《软件测试》项目样题

第三届全国技能大赛广西选拔赛《软件测试》项目样题 模块 A 功能测试&#xff1a;竞赛任务一&#xff1a;设计功能测试用例竞赛任务二&#xff1a;执行功能测试用例竞赛任务三&#xff1a;编写测试报告 模块 B 接口测试&#xff1a;竞赛任务一、新增设备信息测试竞赛任务二、设…

ExpTimerApcRoutine函数分析之作用是ActiveTimerListHead里面移除定时器_etimer

第一部分&#xff1a; VOID ExpTimerApcRoutine ( IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2 ) /* Routine Description: This function is the special …