23种设计模式之责任链模式

server/2024/12/15 22:40:25/

目录

  • 1. 简介
  • 2. 代码
    • 2.1 AbstractLogger(抽象处理者)
    • 2.2 InfoLogger (具体处理者)
    • 2.3 DebugLogger (具体处理者)
    • 2.4 ErrorLogger (具体处理者)
    • 2.5 Test (测试)
    • 2.6 运行结果
    • 2.7 其他
  • 3. 使用场景
  • 4. 优缺点
  • 5. 总结

1. 简介

责任链模式(Chain of Responsibility Pattern) 是一种行为型设计模式,旨在解决请求发送者和接收者之间的耦合问题。通过将多个对象连接成一条链,请求沿着这条链传递,直到某个对象决定处理该请求为止。这种模式允许系统动态地重新组织和分配责任,而不会影响客户端。

责任链模式的结构:
抽象处理者(Handler) :定义处理请求的接口,并包含对后继处理者的引用。抽象处理者通常定义一个处理请求的方法,可以实现后继链。

具体处理者(ConcreteHandler) :实现抽象处理者的接口,负责处理用户请求。如果当前处理者无法处理请求,则会将请求转发给下一个处理者。

2. 代码

设置三个等级的日志,如果加入的警告等级高,会触发更多的日志

2.1 AbstractLogger(抽象处理者)

java">public abstract class AbstractLogger {public static int INFO = 1;public static int DEBUG = 2;public static int ERROR = 3;protected int level;protected AbstractLogger nextLogger;public void setNextLogger(AbstractLogger nextLogger){this.nextLogger = nextLogger;}public void logMessage(int level, String message){if (this.level <= level){write(message);}if (nextLogger != null){nextLogger.logMessage(level, message);}}abstract protected void write(String message);
}

2.2 InfoLogger (具体处理者)

java">public class InfoLogger extends AbstractLogger{public InfoLogger(int level){this.level = level;}@Overrideprotected void write(String message){System.out.println("InfoLogger: " + message);}
}

2.3 DebugLogger (具体处理者)

java">public class DebugLogger extends AbstractLogger{public DebugLogger(int level){this.level = level;}@Overrideprotected void write(String message){System.out.println("Debug Logger: " + message);}
}

2.4 ErrorLogger (具体处理者)

java">public class ErrorLogger extends AbstractLogger{public ErrorLogger(int level){this.level = level;}@Overridepublic void write(String message){System.out.println("Error Console::Logger: " + message);}
}

2.5 Test (测试)

java">public class Test {// 创建责任链public static AbstractLogger getChainOfLoggers() {InfoLogger infoLogger = new InfoLogger(AbstractLogger.INFO);DebugLogger debugLogger = new DebugLogger(AbstractLogger.DEBUG);ErrorLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);infoLogger.setNextLogger(debugLogger);debugLogger.setNextLogger(errorLogger);return infoLogger;}public static void main(String[] args){AbstractLogger loggerChain = Test.getChainOfLoggers();loggerChain.logMessage(AbstractLogger.INFO, "This is an information.");System.out.println("-------------------");loggerChain.logMessage(AbstractLogger.DEBUG, "This is an debug level information.");System.out.println("-------------------");loggerChain.logMessage(AbstractLogger.ERROR, "This is an error information.");}
}

2.6 运行结果

InfoLogger: This is an information.
-------------------
InfoLogger: This is an debug level information.
Debug Logger: This is an debug level information.
-------------------
InfoLogger: This is an error information.
Debug Logger: This is an error information.
Error Console::Logger: This is an error information.

2.7 其他

java">package behavioral.chain;// 抽象处理器
abstract class Approver {protected Approver successor; // 后继处理者public void setSuccessor(Approver successor) {this.successor = successor;}public abstract void processLeaveApplication(LeaveApplication application);
}// 具体处理器 - 班长
class Monitor extends Approver {@Overridepublic void processLeaveApplication(LeaveApplication application) {if (application.getDays() <= 1) {System.out.println("班长批准了请假申请");} else if (successor != null) {successor.processLeaveApplication(application);} else {System.out.println("没有人批准请假申请");}}
}// 具体处理器 - 辅导员
class Counselor extends Approver {@Overridepublic void processLeaveApplication(LeaveApplication application) {if (application.getDays() <= 3) {System.out.println("辅导员批准了请假申请");} else if (successor != null) {successor.processLeaveApplication(application);} else {System.out.println("没有人批准请假申请");}}
}// 具体处理器 - 学生办
class StudentOffice extends Approver {@Overridepublic void processLeaveApplication(LeaveApplication application) {if (application.getDays() <= 7) {System.out.println("学生办批准了请假申请");} else {System.out.println("没有人批准请假申请");}}
}// 请假申请类
class LeaveApplication {private int days;public LeaveApplication(int days) {this.days = days;}public int getDays() {return days;}
}// 客户端代码
public class Client {public static void main(String[] args) {// 创建处理链Approver monitor = new Monitor();Approver counselor = new Counselor();Approver studentOffice = new StudentOffice();monitor.setSuccessor(counselor);counselor.setSuccessor(studentOffice);// 提交请假申请LeaveApplication application1 = new LeaveApplication(1);monitor.processLeaveApplication(application1); // 班长批准LeaveApplication application2 = new LeaveApplication(2);monitor.processLeaveApplication(application2); // 班长批准LeaveApplication application3 = new LeaveApplication(4);monitor.processLeaveApplication(application3); // 辅导员批准LeaveApplication application4 = new LeaveApplication(8);monitor.processLeaveApplication(application4); // 学生办批准}
}

运行结果:

班长批准了请假申请
辅导员批准了请假申请
学生办批准了请假申请
没有人批准请假申请

3. 使用场景

  1. 多个对象处理同一请求:当一个请求需要由多个对象按顺序处理时,责任链模式非常有用。例如,在日志记录系统中,不同级别的日志(如INFO、ERROR、DEBUG)可以由不同的处理器处理。同样,在审批流程中,一个请求可以由多个审批者依次审批,直到最终批准或拒绝。
  2. 动态处理流程:当请求的处理流程不确定,且每个处理节点是否处理请求都不确定时,责任链模式提供了一种灵活的机制。例如,在Web应用开发中,可以通过责任链模式实现过滤器链式处理,每个过滤器负责处理特定的请求类型。
  3. 权限校验和拦截器设计:在权限校验的登录拦截器中,责任链模式可以用于动态地添加或删除处理者,以适应业务需求的变化。此外,责任链模式也被应用于拦截器设计,如Cicada框架中的拦截器调用。
  4. 事件处理系统:在GUI事件处理中,责任链模式可以用于处理用户交互事件,每个事件处理器负责处理特定的用户交互事件。
  5. 安全防护:在安全场景中,责任链模式可以用于防止XSS攻击,通过创建一个FilterChain,包含多个过滤器,每个过滤器负责处理请求并传递给下一个过滤器,直到所有过滤器完成处理。
  6. 生产流程和报销审批流程:在生产线中,责任链模式可以用于拆分汽车零件的安装工作,并分配给各安装节点,最终实现汽车从零件到成品的量产。在报销审批流程中,责任链模式可以确保请假流程的合理性和效率。
  7. 复杂请求处理责任链模式适用于需要处理复杂业务逻辑的场景,通过将请求的处理链式传递,可以有效地分解和组合处理步骤,提高系统的灵活性和可维护性。

责任链模式通过降低耦合度、提高系统的灵活性和可扩展性,适用于需要动态处理请求且处理逻辑可能发生变化的场景。然而,在使用责任链模式时需注意其潜在的性能问题和配置不当可能导致的错误处理。

4. 优缺点

  • 优点:
  1. 降低耦合度责任链模式允许请求的发送者和接收者之间保持松散耦合,减少了对象之间的直接依赖关系。
  2. 增强灵活性:可以通过动态地增加或删除处理者来改变请求的处理流程,从而提高系统的灵活性和可扩展性。
  3. 职责单一:每个处理者只负责自己感兴趣的请求,这使得每个处理者的职责更加明确,符合单一职责原则。
  4. 代码清晰:将复杂的逻辑分解到多个处理节点中,职责单一,使得代码结构更加清晰。
  5. 符合开闭原则:可以在不修改现有代码的情况下,通过添加新的处理者来扩展系统功能。
  • 缺点:
  1. 性能问题:当责任链较长时,请求需要遍历整个链才能找到合适的处理者,这可能导致性能下降。
  2. 调试困难:由于请求在责任链中传递,调试时可能会遇到跟踪请求流向的困难,特别是在链条较长的情况下。
  3. 请求可能未被处理:如果责任链中的每个处理者都不能处理请求,那么请求可能会一直传递到链的末端而未被处理。
  4. 维护复杂性增加:责任链的动态修改可能增加系统的复杂度,需要额外的管理措施来确保链的有效性和合理性。

责任链模式在实际应用中可以显著提高系统的灵活性和可扩展性,但同时也需要注意其潜在的性能和调试问题。在设计时应合理控制责任链的长度,并确保责任链的正确配置以避免不必要的性能损失和调试困难。

5. 总结

设置一个链,涉资一个等级,如果输入的等级很高,就往后运行。


http://www.ppmy.cn/server/150455.html

相关文章

基于51单片机的简易时钟/定时器闹钟proteus仿真

地址&#xff1a; https://pan.baidu.com/s/1uez4cwZuXpchmihmRqnLEg 提取码&#xff1a;1234 仿真图&#xff1a; 芯片/模块的特点&#xff1a; AT89C52/AT89C51简介&#xff1a; AT89C52/AT89C51是一款经典的8位单片机&#xff0c;是意法半导体&#xff08;STMicroelectro…

性能测试工具有哪些?原理是什么?怎么选择适合的工具?

前言 本篇文章主要简单总结下性能测试工具的原理以及如何选型。性能测试和功能测试不同&#xff0c;性能测试的执行是基本功能的重复和并发&#xff0c;需要模拟多用户&#xff0c;在性能测试执行时需要监控指标参数&#xff0c;同时性能测试的结果不是那么显而易见&#xff0…

Elasticsearch之mapping属性设置讲解与实战

Elasticsearch之Mapping属性设置讲解与实战 1. 引言 1.1 博客目的与读者定位 本篇技术博客旨在为Elasticsearch的中级用户及开发者提供一个深入浅出的Mapping属性设置指南。无论您是正在构建新的搜索应用,还是希望优化现有Elasticsearch集群的性能,本文都将为您提供详尽的…

代码随想录算法训练营第三十二天|动态规划理论基础|LC509.肥波那些数|LC70.爬楼梯|LC746.使用最小花费爬楼梯

动态规划理论基础 解释&#xff1a;动态规划&#xff0c;英文&#xff1a;Dynamic Programming&#xff0c;简称DP&#xff1b;如果某一问题有很多重叠子问题&#xff0c;使用动态规划是最有效的。 动态规划五部曲&#xff1a; 1、确定dp数组&#xff08;dp table&#xff09;…

linux下编程记录

** gcc ** 编写C源代码 首先&#xff0c;创建一个C源代码文件&#xff0c;例如 main.cpp&#xff0c;并编辑你的代码。比如&#xff1a; #include <iostream> using namespace std;int main() {cout << "Hello, World!" << endl;return 0;}使用…

HCIA-Access V2.5_2_2网络通信基础_TCP/IP协议栈报文封装

TCP/IP协议栈的封装过程 用户从应用层发出数据先会交给传输层&#xff0c;传输层会添加TCP或者UDP头部&#xff0c;然后交给网络层&#xff0c;网络层会添加IP头部&#xff0c;然后交给数据链路层&#xff0c;数据链路层会添加以太网头部和以太网尾部&#xff0c;最后变成01这样…

基于nginx和ffmpeg搭建HTTP FLV流媒体服务器

一、简介 整体是使用nginx搭建HTTP FLV流媒体服务器&#xff1a; 流程&#xff1a;音视频->rtmp->http-flv 音视频转为rtmp需要借助ffmpeg转化。 rtmp转为http-flv需要借助nginx转化。 nginx-http-flv-module是基于nginx-rtmp-module开发的&#xff0c;包含nginx-rt…

Responder:功能强大的安全工具介绍

一、概述 定义与定位 Responder 是一款专为渗透测试人员和安全研究人员设计的工具。它专注于在网络环境中处理各种协议的响应&#xff0c;旨在帮助检测和利用网络中的潜在安全漏洞&#xff0c;尤其是与身份验证和网络服务相关的漏洞。主要运行在基于 Windows 和 Linux 的操作系…