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

GPT带我学-设计模式-责任链模式

什么是责任链模式

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它通过将请求沿着一条处理链传递,直到某个处理器处理该请求或链的末端被到达,从而避免请求的发送者和接收者之间的耦合。

关键要点

  • 请求处理链:在责任链模式中,请求会沿着一条由多个处理器(Handler)组成的链传递,每个处理器都有机会处理请求。处理器可以选择处理请求、部分处理请求,或者将请求传递给下一个处理器。

  • 解耦:请求的发送者和处理者解耦,发送者不需要知道具体哪个处理器会处理请求,这提高了系统的灵活性和可扩展性。

结构

责任链模式包含以下几个主要角色:

  1. 处理器(Handler):定义了处理请求的接口,并实现链中下一个处理器的引用。通常包含一个 handleRequest 方法来处理请求。

  2. 具体处理器(ConcreteHandler):处理器接口的实现类,负责实际处理请求。如果处理不了,它会将请求传递给链中的下一个处理器。

  3. 客户端(Client):发出请求的客户端,并将请求发送到链上的第一个处理器。

示例1

假设我们有一个系统,它处理不同级别的用户请求:普通用户请求、经理请求和总监请求。系统按责任链的方式处理这些请求,只有合适的处理器才能处理特定的请求。

代码实现
  1. 定义处理器接口:
// 处理器接口,定义处理请求的方法
public abstract class Handler {protected Handler nextHandler;// 设置链中的下一个处理器public void setNextHandler(Handler nextHandler) {this.nextHandler = nextHandler;}// 处理请求的方法public abstract void handleRequest(String request);
}
  1. 实现具体处理器:
// 具体处理器:处理普通用户请求
public class UserHandler extends Handler {@Overridepublic void handleRequest(String request) {if (request.equals("User Request")) {System.out.println("UserHandler 处理请求: " + request);} else if (nextHandler != null) {nextHandler.handleRequest(request);}}
}// 具体处理器:处理经理请求
public class ManagerHandler extends Handler {@Overridepublic void handleRequest(String request) {if (request.equals("Manager Request")) {System.out.println("ManagerHandler 处理请求: " + request);} else if (nextHandler != null) {nextHandler.handleRequest(request);}}
}// 具体处理器:处理总监请求
public class DirectorHandler extends Handler {@Overridepublic void handleRequest(String request) {if (request.equals("Director Request")) {System.out.println("DirectorHandler 处理请求: " + request);} else if (nextHandler != null) {nextHandler.handleRequest(request);}}
}
  1. 客户端代码:
public class ChainOfResponsibilityDemo {public static void main(String[] args) {// 创建处理链Handler userHandler = new UserHandler();Handler managerHandler = new ManagerHandler();Handler directorHandler = new DirectorHandler();userHandler.setNextHandler(managerHandler);  // 设置链的下一个处理器managerHandler.setNextHandler(directorHandler);// 发送请求userHandler.handleRequest("User Request");       // 由 UserHandler 处理userHandler.handleRequest("Manager Request");    // 由 ManagerHandler 处理userHandler.handleRequest("Director Request");   // 由 DirectorHandler 处理userHandler.handleRequest("Unknown Request");    // 没有处理器能处理}
}

输出结果:

UserHandler 处理请求: User Request
ManagerHandler 处理请求: Manager Request
DirectorHandler 处理请求: Director Request

解释

  • 处理链:在这个示例中,UserHandlerManagerHandlerDirectorHandler 组成了一条处理链。每个处理器尝试处理请求,如果不能处理,就将请求传递给链中的下一个处理器。

  • 处理请求:每个处理器只有在它能够处理的情况下才会处理请求,否则它会将请求传递给下一个处理器。

责任链模式的优点

  1. 解耦请求发送者和接收者:请求发送者不需要知道哪个处理器会处理请求,减少了耦合。

  2. 动态组合处理器:可以动态地改变处理链,增加或删除处理器,而不影响请求发送者。

责任链模式的缺点

  1. 链可能变得很长:如果处理链很长,可能会影响性能,特别是每个处理器都不处理请求时。

  2. 可能没有处理器处理请求:如果链的末端都没有处理请求的处理器,可能会导致请求未被处理。

责任链模式广泛应用于需要动态决定处理请求顺序的场景,如权限验证、日志记录、请求过滤等。

示例2:客服系统

场景
假设你有一个在线客服系统,它负责处理用户的各种请求(如一般查询、技术支持、投诉等)。用户的请求根据内容不同会由不同级别的客服人员处理。如果一个客服无法处理该请求,他们会将请求传递给下一级别的客服。

角色对应:

  • 处理器(Handler):不同级别的客服人员(如普通客服、技术支持、主管)。
  • 请求:用户的服务请求。

示例代码

  1. 定义处理器接口:
// 处理器接口,定义处理请求的方法
public abstract class CustomerSupportHandler {protected CustomerSupportHandler nextHandler;// 设置链中的下一个处理器public void setNextHandler(CustomerSupportHandler nextHandler) {this.nextHandler = nextHandler;}// 处理请求的方法public abstract void handleRequest(String request);
}
  1. 实现具体处理器:
// 具体处理器:普通客服
public class GeneralSupportHandler extends CustomerSupportHandler {@Overridepublic void handleRequest(String request) {if (request.equals("General Inquiry")) {System.out.println("GeneralSupport 处理请求: " + request);} else if (nextHandler != null) {nextHandler.handleRequest(request);}}
}// 具体处理器:技术支持
public class TechnicalSupportHandler extends CustomerSupportHandler {@Overridepublic void handleRequest(String request) {if (request.equals("Technical Issue")) {System.out.println("TechnicalSupport 处理请求: " + request);} else if (nextHandler != null) {nextHandler.handleRequest(request);}}
}// 具体处理器:投诉处理
public class ComplaintHandler extends CustomerSupportHandler {@Overridepublic void handleRequest(String request) {if (request.equals("Complaint")) {System.out.println("ComplaintHandler 处理请求: " + request);} else if (nextHandler != null) {nextHandler.handleRequest(request);}}
}
  1. 客户端代码:
public class CustomerSupportDemo {public static void main(String[] args) {// 创建处理链CustomerSupportHandler generalSupport = new GeneralSupportHandler();CustomerSupportHandler technicalSupport = new TechnicalSupportHandler();CustomerSupportHandler complaintHandler = new ComplaintHandler();generalSupport.setNextHandler(technicalSupport);  // 设置链的下一个处理器technicalSupport.setNextHandler(complaintHandler);// 发送请求generalSupport.handleRequest("General Inquiry");    // 由 GeneralSupport 处理generalSupport.handleRequest("Technical Issue");    // 由 TechnicalSupport 处理generalSupport.handleRequest("Complaint");          // 由 ComplaintHandler 处理generalSupport.handleRequest("Unknown Request");    // 没有处理器能处理}
}

输出结果:

GeneralSupport 处理请求: General Inquiry
TechnicalSupport 处理请求: Technical Issue
ComplaintHandler 处理请求: Complaint

解释

  • 普通客服处理一般查询:如果用户请求是一般查询(如服务信息),GeneralSupportHandler 会处理它。

  • 技术支持处理技术问题:如果请求是技术问题,GeneralSupportHandler 会将请求传递给 TechnicalSupportHandler 处理。

  • 投诉处理:如果请求是投诉,最终会由 ComplaintHandler 处理。

  • 未处理的请求:如果请求类型不在这些处理器的处理范围内,最终请求不会被处理。

责任链模式的应用场景

  • 权限验证:如用户访问某个系统功能时,首先检查权限,若权限不足则依次传递给更高级别的检查器。

  • 请求过滤:如Web服务器接收到的请求需要经过多个过滤器(如安全过滤、日志记录、数据格式验证)才能最终处理。

  • 任务审批流程:如企业内部的审批流程,审批请求由不同级别的管理者依次处理,直到最终被批准或拒绝。

这个例子显示了责任链模式如何在实际应用中灵活应对不同种类的请求,而无需请求发送者知道具体哪个处理器会处理它。通过这种方式,系统可以轻松地扩展或修改请求处理流程,而不需要改动客户端代码。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 游戏开发设计模式之外观模式
  • C语言补习课
  • 【GPT】基于GPT_API_free做一个自己的gpt
  • 服务器死机/无故宕机排查思路/服务器起不来
  • 一篇搞懂classpath,resources
  • 【STM32H743】将全局变量定义到指定内存MDK
  • 设计模式--装饰器模式
  • python脚本开头怎么写
  • 【零知识证明】MiMC哈希函数电路
  • 罗素悖论 是集合论中的一个经典悖论
  • 【C语言】十六进制、二进制、字节、位
  • 【论文阅读】Single-Stage Visual Query Localization in Egocentric Videos
  • 一键编译QT5源码脚本(交叉编译arm64、mips64版本)
  • 春秋云镜(ZZCMS 2023)·CVE-2023-50104
  • 深入探究Nginx中的URL哈希负载均衡策略
  • 2018一半小结一波
  • CentOS7 安装JDK
  • JavaScript创建对象的四种方式
  • PHP的类修饰符与访问修饰符
  • Rancher-k8s加速安装文档
  • spring + angular 实现导出excel
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • 阿里研究院入选中国企业智库系统影响力榜
  • 关于使用markdown的方法(引自CSDN教程)
  • 汉诺塔算法
  • 猴子数据域名防封接口降低小说被封的风险
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 容器服务kubernetes弹性伸缩高级用法
  • 深入浅出webpack学习(1)--核心概念
  • 为什么要用IPython/Jupyter?
  • 要让cordova项目适配iphoneX + ios11.4,总共要几步?三步
  • 走向全栈之MongoDB的使用
  • 摩拜创始人胡玮炜也彻底离开了,共享单车行业还有未来吗? ...
  • 如何正确理解,内页权重高于首页?
  • ​Java基础复习笔记 第16章:网络编程
  • #HarmonyOS:Web组件的使用
  • #stm32整理(一)flash读写
  • (02)Hive SQL编译成MapReduce任务的过程
  • (1)bark-ml
  • (152)时序收敛--->(02)时序收敛二
  • (2024)docker-compose实战 (8)部署LAMP项目(最终版)
  • (AngularJS)Angular 控制器之间通信初探
  • (六)c52学习之旅-独立按键
  • (数据大屏)(Hadoop)基于SSM框架的学院校友管理系统的设计与实现+文档
  • (四)JPA - JQPL 实现增删改查
  • (四)js前端开发中设计模式之工厂方法模式
  • (一)kafka实战——kafka源码编译启动
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .net 8 发布了,试下微软最近强推的MAUI
  • .NET CLR基本术语
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .NET Framework 服务实现监控可观测性最佳实践
  • .NET 中的轻量级线程安全
  • .NET/C# 使用 SpanT 为字符串处理提升性能