欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 游戏 > Java 与设计模式(17):责任链模式

Java 与设计模式(17):责任链模式

2025/2/22 4:19:07 来源:https://blog.csdn.net/qq_42449106/article/details/145763954  浏览:    关键词:Java 与设计模式(17):责任链模式

一、定义

责任链模式的核心思想是:把多个对象串联起来,形成一条链子,每个对象都有机会处理请求。当一个请求进入这条链子时,每个对象都会检查自己是否能处理这个请求,如果能处理就处理,如果不能处理就传递给下一个对象。

二、Java示例

举个简单的例子:
假设你在学校里遇到了一个问题,你想请假。你会找你的班主任老师请假,班主任老师可能会批准你的请求,也可能觉得需要找校长来决定。如果班主任老师不能决定,她就会把你的请求转给校长。这里,班主任和校长就形成了一个“责任链”。

具体流程:
你向班主任老师提出请假请求。

班主任老师检查你的请假理由: 如果理由充分(比如生病了,有医院证明),她会直接批准你的请求。
如果理由不充分(比如想出去玩),她会觉得需要找校长来决定。

如果班主任老师不能决定,她会把你的请求转给校长。

校长会检查你的请假理由: 如果理由充分,他会批准你的请求。 如果理由不充分,他会拒绝你的请求。

我们可以用简单的代码来表示这个过程:

// 定义一个处理请求的接口
public interface Handler {void handleRequest(String request);
}// 班主任类
public class ClassTeacher implements Handler {private Handler nextHandler; // 下一个处理者public ClassTeacher(Handler nextHandler) {this.nextHandler = nextHandler;}@Overridepublic void handleRequest(String request) {if (request.contains("生病")) {System.out.println("班主任批准了你的请假请求!");} else {System.out.println("班主任不能决定,转给校长处理。");nextHandler.handleRequest(request); // 传递给下一个处理者}}
}// 校长类
public class Principal implements Handler {@Overridepublic void handleRequest(String request) {if (request.contains("出去玩")) {System.out.println("校长拒绝了你的请假请求!");} else {System.out.println("校长批准了你的请假请求!");}}
}// 测试代码
public class Main {public static void main(String[] args) {// 创建校长对象Principal principal = new Principal();// 创建班主任对象,并将校长作为下一个处理者ClassTeacher classTeacher = new ClassTeacher(principal);// 提出请假请求classTeacher.handleRequest("我想请假,因为我生病了。");classTeacher.handleRequest("我想请假,因为我想出去玩。");}
}

输出结果:
班主任批准了你的请假请求!
班主任不能决定,转给校长处理。
校长拒绝了你的请假请求!

Handler 接口:定义了一个处理请求的方法 handleRequest。
ClassTeacher类:班主任是第一个处理者,她会检查请求的内容。如果请求是“生病”,她会直接批准;如果是“出去玩”,她会把请求传递给校长。
Principal类:校长是第二个处理者,他会检查班主任传递过来的请求。如果请求是“出去玩”,他会拒绝;如果是其他理由,他会批准。

三、优点

  1. 降低耦合度
    优点:责任链模式将请求的发送者和接收者解耦,使得它们之间没有直接的联系。发送者只需要将请求发送到责任链的起点,而不需要知道具体的接收者和处理逻辑。
    示例:在一个审批流程中,申请人只需要将申请提交给第一个审批人,而不需要知道后续的审批人和审批逻辑。
  2. 提高灵活性
    优点:责任链模式使得系统更加灵活,可以动态地添加、删除或修改处理者,而不需要修改现有的代码。这使得系统能够更好地应对需求的变化。
    示例:在一个日志处理系统中,可以动态地添加新的日志处理者,而不需要修改现有的日志处理链。
  3. 简化代码
    优点:责任链模式可以简化代码,避免使用大量的条件语句(如 if-else 或 switch)来决定请求的处理者。每个处理者只需要关注自己的处理逻辑,而不需要知道其他处理者的逻辑。
    示例:在一个审批流程中,每个审批人只需要关注自己的审批逻辑,而不需要知道其他审批人的逻辑。
  4. 支持动态组合
    优点:责任链模式支持动态组合处理者,可以根据不同的需求动态地组合处理者,形成不同的处理链。
    示例:在一个任务处理系统中,可以根据任务的类型和优先级动态地组合处理者,形成不同的处理链。
  5. 支持日志记录和事务管理
    优点:责任链模式可以在处理者中添加日志记录和事务管理的功能,使得系统更加健壮和可靠。
    示例:在一个事务管理系统中,可以在每个处理者中添加日志记录和事务管理的功能,确保操作的完整性和一致性。
  6. 支持请求的动态处理
    优点:责任链模式支持请求的动态处理,可以根据请求的类型和内容动态地选择处理者。
    示例:在一个请求处理系统中,可以根据请求的类型和内容动态地选择处理者,使得请求能够得到最合适的处理。
  7. 支持请求的多级处理
    优点:责任链模式支持请求的多级处理,可以将请求传递给多个处理者,每个处理者都可以对请求进行处理。
    示例:在一个审批流程中,一个请求可以经过多个审批人,每个审批人都可以对请求进行审批。
  8. 提高代码的可维护性
    优点:责任链模式将请求的处理逻辑分散到多个处理者中,使得代码结构更加清晰,易于维护和管理。
    示例:在一个日志处理系统中,每个日志处理者的逻辑相对独立,易于维护和管理。
  9. 支持请求的动态路由
    优点:责任链模式支持请求的动态路由,可以根据请求的类型和内容动态地选择处理链。
    示例:在一个请求处理系统中,可以根据请求的类型和内容动态地选择处理链,使得请求能够得到最合适的处理。
  10. 支持请求的动态优先级
    优点:责任链模式支持请求的动态优先级,可以根据请求的优先级动态地选择处理者。
    示例:在一个任务处理系统中,可以根据任务的优先级动态地选择处理者,使得高优先级的任务能够得到优先处理。

四、缺点

  1. 性能开销
    缺点:责任链模式可能会导致性能开销增加,特别是在责任链较长的情况下。每个请求都需要逐个传递给链中的每个处理者,直到找到合适的处理者。如果链中的处理者数量较多,可能会导致请求处理的延迟。
    示例:在一个复杂的审批流程中,如果审批链中有多个审批者,每个审批者都需要检查请求,这可能会导致请求处理的延迟。
  2. 难以调试
    缺点:责任链模式可能会使调试变得困难。由于请求的处理过程分散在多个处理者中,如果出现问题,需要逐一检查每个处理者,这会增加调试的复杂性。
    示例:在一个复杂的日志处理系统中,如果日志处理链中有多个处理者,每个处理者都需要处理日志,如果日志处理出现问题,需要逐一检查每个处理者,这会增加调试的难度。
  3. 责任不明确
    缺点:责任链模式可能会导致责任不明确。由于请求的处理过程分散在多个处理者中,每个处理者都有机会处理请求,但最终由哪个处理者处理请求并不明确。这可能会导致责任推诿或重复处理。
    示例:在一个复杂的审批流程中,如果审批链中的每个审批者都有机会处理请求,但最终由哪个审批者处理请求并不明确,这可能会导致责任推诿或重复审批。
  4. 难以确定请求的处理顺序
    缺点:责任链模式可能会使请求的处理顺序难以确定。由于请求的处理过程分散在多个处理者中,每个处理者都有机会处理请求,但处理顺序并不固定。这可能会导致请求的处理结果不稳定。
    示例:在一个复杂的日志处理系统中,如果日志处理链中的每个处理者都有机会处理日志,但处理顺序并不固定,这可能会导致日志处理的结果不稳定。
  5. 增加系统的复杂性
    缺点:责任链模式会增加系统的复杂性。由于需要定义多个处理者,并将它们串联成一条链,这会增加系统的复杂性。对于简单的请求处理,使用责任链模式可能会显得过于复杂。
    示例:在一个简单的日志处理系统中,如果只需要一个日志处理者,使用责任链模式可能会显得过于复杂,增加系统的复杂性。
  6. 难以维护
    缺点:责任链模式可能会使维护变得困难。由于请求的处理过程分散在多个处理者中,如果需要修改请求的处理逻辑,需要逐一修改每个处理者,这会增加维护的难度。
    示例:在一个复杂的审批流程中,如果需要修改审批逻辑,需要逐一修改每个审批者,这会增加维护的难度。
  7. 可能导致循环引用
    缺点:责任链模式可能会导致循环引用。如果责任链中的处理者之间存在循环引用,可能会导致请求在链中无限循环,无法得到处理。
    示例:在一个复杂的审批流程中,如果审批链中的审批者之间存在循环引用,可能会导致请求在链中无限循环,无法得到处理。
  8. 难以扩展
    缺点:责任链模式可能会使扩展变得困难。由于请求的处理过程分散在多个处理者中,如果需要增加新的处理者,需要修改现有的责任链,这会增加扩展的难度。
    示例:在一个复杂的日志处理系统中,如果需要增加新的日志处理者,需要修改现有的日志处理链,这会增加扩展的难度。

五、使用场景

责任链模式(Chain of Responsibility Pattern)在软件开发中有许多典型的应用场景。以下是一些常见的场景,帮助你更好地理解责任链模式的应用:

  1. 审批流程
    场景描述:在一个企业管理系统中,员工提交的请假申请、报销申请等需要经过多个层级的审批,如部门经理、财务主管、总经理等。
    应用方式:每个审批层级作为一个处理者,形成一条责任链。申请在链中传递,每个处理者根据自己的权限和规则决定是否批准或拒绝申请,或者将申请传递给下一个处理者。

  2. 日志处理
    场景描述:在一个日志处理系统中,日志信息需要经过多个处理步骤,如过滤、格式化、存储等。
    应用方式:每个处理步骤作为一个处理者,形成一条责任链。日志信息在链中传递,每个处理者对日志进行相应的处理,然后将处理后的日志传递给下一个处理者。

  3. 异常处理
    场景描述:在一个复杂的系统中,可能会发生多种类型的异常,每种异常需要不同的处理方式。
    应用方式:每个异常处理者作为一个处理者,形成一条责任链。当异常发生时,异常信息在链中传递,每个处理者检查自己是否能处理该异常,如果能处理则进行处理,否则将异常传递给下一个处理者。

  4. 任务调度
    场景描述:在一个任务调度系统中,任务需要经过多个处理步骤,如任务分配、任务执行、任务监控等。
    应用方式:每个处理步骤作为一个处理者,形成一条责任链。任务在链中传递,每个处理者对任务进行相应的处理,然后将处理后的任务传递给下一个处理者。

  5. 权限验证
    场景描述:在一个权限管理系统中,用户的请求需要经过多个层级的权限验证,如用户认证、角色验证、权限检查等。
    应用方式:每个验证层级作为一个处理者,形成一条责任链。用户请求在链中传递,每个处理者根据自己的验证规则决定是否允许请求通过,或者将请求传递给下一个处理者。

  6. 请求路由
    场景描述:在一个请求处理系统中,请求需要根据不同的条件路由到不同的处理者,如根据请求类型、请求内容、用户角色等。
    应用方式:每个路由层级作为一个处理者,形成一条责任链。请求在链中传递,每个处理者根据自己的路由规则决定是否处理请求,或者将请求传递给下一个处理者。

  7. 数据处理
    场景描述:在一个数据处理系统中,数据需要经过多个处理步骤,如数据清洗、数据转换、数据存储等。
    应用方式:每个处理步骤作为一个处理者,形成一条责任链。数据在链中传递,每个处理者对数据进行相应的处理,然后将处理后的数据传递给下一个处理者。

  8. 消息处理
    场景描述:在一个消息处理系统中,消息需要经过多个处理步骤,如消息解析、消息验证、消息存储等。
    应用方式:每个处理步骤作为一个处理者,形成一条责任链。消息在链中传递,每个处理者对消息进行相应的处理,然后将处理后的消息传递给下一个处理者。

  9. 工作流系统
    场景描述:在一个工作流系统中,任务需要经过多个处理步骤,如任务分配、任务执行、任务监控、任务完成等。
    应用方式:每个处理步骤作为一个处理者,形成一条责任链。任务在链中传递,每个处理者对任务进行相应的处理,然后将处理后的任务传递给下一个处理者。

  10. 过滤器链
    场景描述:在一个Web应用中,请求和响应需要经过多个过滤器,如安全过滤器、日志过滤器、性能监控过滤器等。
    应用方式:每个过滤器作为一个处理者,形成一条责任链。请求和响应在链中传递,每个过滤器对请求和响应进行相应的处理,然后将处理后的请求和响应传递给下一个过滤器。

六、注意事项

  1. 明确责任链的结构
    注意:在设计责任链时,需要明确每个处理者的职责和处理顺序,确保责任链的结构清晰、合理。
    建议:在设计责任链时,可以使用类图或其他设计工具来明确每个处理者的职责和处理顺序,确保责任链的结构清晰、合理。
  2. 避免责任链过长
    注意:责任链过长可能会导致性能下降和调试困难。如果责任链过长,可能会导致请求在链中传递的时间过长,增加系统的响应时间。
    建议:在设计责任链时,尽量避免责任链过长。如果责任链过长,可以考虑将链中的处理者进行分组或合并,减少链的长度。
  3. 明确每个处理者的职责
    注意:每个处理者应该有明确的职责,避免职责重叠或职责不清。如果处理者的职责不明确,可能会导致请求处理的混乱。
    建议:在设计处理者时,确保每个处理者的职责明确、单一,避免职责重叠或职责不清。
  4. 处理请求的传递
    注意:在传递请求时,需要确保请求能够正确地传递到下一个处理者。如果请求传递不当,可能会导致请求处理的失败。
    建议:在设计处理者时,确保请求能够正确地传递到下一个处理者。可以在处理者中添加请求传递的逻辑,确保请求能够正确地传递。
  5. 处理请求的终止
    注意:在责任链中,需要有一个明确的终止条件,避免请求在链中无限循环。如果请求在链中无限循环,可能会导致系统崩溃。
    建议:在设计责任链时,确保有一个明确的终止条件。可以在处理者中添加终止条件的判断,确保请求能够在适当的时候终止。
  6. 处理异常情况
    注意:在责任链中,需要考虑异常情况的处理。如果处理者在处理请求时发生异常,需要有相应的处理机制,避免系统崩溃。
    建议:在设计处理者时,添加异常处理的逻辑,确保在处理请求时发生异常时能够进行相应的处理。可以在处理者中添加异常捕获和处理的代码,确保系统的稳定性。
  7. 避免责任链中的循环引用
    注意:在责任链中,需要避免循环引用。如果责任链中存在循环引用,可能会导致请求在链中无限循环,增加系统的复杂性和不确定性。
    建议:在设计责任链时,确保责任链中不存在循环引用。可以在设计责任链时使用类图或其他设计工具来检查责任链的结构,避免循环引用。
  8. 支持动态添加和删除处理者
    注意:责任链模式的一个重要特点是支持动态添加和删除处理者。在设计责任链时,需要确保能够动态地添加和删除处理者,而不需要修改现有的代码。
    建议:在设计责任链时,使用接口或抽象类来定义处理者的职责,确保能够动态地添加和删除处理者。可以在责任链中使用集合或其他数据结构来管理处理者,支持动态添加和删除。
  9. 支持请求的动态处理
    注意:在责任链中,需要支持请求的动态处理。如果请求的处理逻辑需要动态变化,需要确保责任链能够支持这种变化。
    建议:在设计责任链时,确保请求的处理逻辑能够动态变化。可以在处理者中添加动态处理的逻辑,支持请求的动态处理。
  10. 注意性能影响
    注意:责任链模式可能会增加系统的性能开销,特别是在责任链较长的情况下。在设计责任链时,需要考虑性能的影响,避免因责任链过长而导致性能下降。
    建议:在设计责任链时,尽量减少责任链的长度,避免不必要的处理者。可以在设计责任链时使用性能分析工具来评估责任链的性能,确保系统的性能满足要求。

七、在spring 中的应用

  1. 过滤器链(Filter Chain)
    在 Spring MVC 中,过滤器链是一个典型的责任链模式应用。每个过滤器都可以对请求或响应进行操作,并决定是否继续调用链中的下一个过滤器。
  2. 配置解析链(Configuration Parsing Chain)
    在 Spring 的配置解析过程中,责任链模式也被广泛应用。每个解析器(如 BeanDefinitionParser)都有机会解析配置文件中的特定元素,并将未处理的元素传递给下一个解析器。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词