责任链模式 + 策略模式:优雅处理多级请求的方式

一、责任链模式的定义

责任链模式(Chain of Responsibility Pattern) 属于行为设计模式的一种,它为请求构建了一条传递路径,请求会沿着这条处理链不断传递,直至链上的某个对象对其进行处理。这种模式使得请求的发送者无需知晓具体由哪个对象来处理请求,链上的各个处理对象既可以尝试处理请求,也能将请求继续传递给下一个对象。

源代码关注公众号:码猿技术专栏,回复关键词:责任链 获取!

责任链模式示意图

核心要点:该模式旨在将请求的发送者与接收者解耦,借助多个对象组成的链条,让请求在链上依次传递,直至得到处理。


二、责任链模式的特性

  1. 解耦发送与处理:请求的发送方无需了解具体的处理对象是谁,这极大地增强了系统的灵活性与扩展性,使得系统在面对变化时能够更加从容应对。
  2. 动态逻辑组合:能够根据实际需求动态调整责任链的结构,灵活地添加或移除处理者,以适应不同的业务场景。
  3. 单一职责原则:责任链模式把每个验证逻辑封装到独立的处理器中,每个处理器仅负责单一的验证任务,符合软件开发中的单一职责原则,提高了代码的可维护性。
  4. 良好的可扩展性:当需要增加新的验证逻辑时,处理者只需继承统一的接口并添加新的处理器即可,无需对现有的代码进行修改,降低了代码的耦合度。
  5. 清晰的流程结构:将所有的验证逻辑组织在一起,使得代码结构更加清晰易懂,便于开发人员进行理解和维护。

三、责任链模式与策略模式结合的价值

  • 责任链模式的作用:主要用于动态处理**请求,将多个处理逻辑按照一定的顺序串联起来,形成一个完整的处理流程。
  • 策略模式的作用:其核心是封装一组算法,使得在运行时可以根据具体需求动态选择合适的算法进行处理。

两者结合的优势:

  • 责任链模式负责将请求依次传递给各个处理者,而策略模式则为每个处理者定义了具体的处理逻辑,两者相辅相成。
  • 通过结合使用,可以实现既能够动态构建责任链,又能灵活应用不同策略来处理请求的需求,提高系统的适应性和灵活性。

四、责任链模式解决的问题

  1. 降低耦合度:将请求的处理者从请求的发送者中分离出来,使得处理者可以独立进行扩展或变更,减少了模块之间的依赖。
  2. 简化多条件判断 :避免在代码中使用大量的 if-elseswitch-case 语句,使代码更加简洁易懂,提高了代码的可读性和可维护性。
  3. 增强灵活性:通过责任链的动态组合,可以轻松调整请求的传递逻辑,也可以方便地插入新的处理者,以满足不断变化的业务需求。关注工众号:码猿技术专栏,回复关键词:1111 获取阿里内部Java性能调优手册!
  4. 减少代码重复:每个处理者只专注于处理自己关心的部分,避免了代码的重复编写,提高了代码的复用性。

五、代码中的责任链模式剖析

场景 1:商品上架逻辑(多重校验)

下面以商品上架逻辑(如校验商品信息、库存信息等)为例,详细介绍如何实现责任链模式。

  1. 定义责任链抽象接口
  1. 定义商品上架的责任链标识
  1. 定义每个处理器的通用行为
  1. 定义商品上架的责任链处理器
  1. 调用责任链进行处理

上述代码构建了一个基于 责任链模式 的电商系统,主要用于处理复杂的业务逻辑,如商品上架模板的创建。该模式将每个业务逻辑封装到独立的处理器(Handler)中,并将这些处理器串联成一个链,通过统一的入口执行每一步处理操作,提高了系统的可维护性和扩展性。


1. 代码的组成部分与职责解析

(1) 责任链抽象接口:MerchantAdminAbstractChainHandler

  • 此接口定义了责任链中的基础行为:
    • void handler(T requestParam) :这是责任链的核心方法,每个处理器都会接收到传入的参数 requestParam,并依据具体的业务逻辑进行相应的处理。关注工众号:码猿技术专栏,回复关键词:1111 获取阿里内部Java性能调优手册!
    • 设计思路T 为泛型参数,可适配不同类型的业务场景,如对象校验、数据处理等。若某个处理器不满足条件,可通过抛出异常或提供返回值来中断后续处理器的运行,每个处理器仅负责完成自身的一部分逻辑,遵循模块化设计原则。

(2) 抽象处理器接口:MerchantAdminAbstractChainHandler

  • 该接口定义了责任链中每个节点的通用行为:
    • void handler(T requestParam) :作为责任链的核心方法,它定义了如何处理传入的请求参数 requestParam。每个实现类会根据具体的业务需求,在该方法中实现自己的处理逻辑,例如参数校验、数据转换等。若某个处理环节出现错误,可通过抛出异常中断责任链的执行。
    • String mark() :返回当前处理器所属的责任链标识(Mark),不同的责任链可通过 mark() 值进行分组管理。例如在商品上架创建责任链中,mark() 可返回 MERCHANT_ADMIN_CREATE_PRODUCT_TEMPLATE_KEY
    • int getOrder() :用于定义处理器的执行顺序。通过实现 Ordered 接口的 getOrder() 方法,开发者能够灵活控制每个处理器在责任链中的执行顺序。默认值为 Ordered.LOWEST_PRECEDENCE(优先级最低),可根据需求覆盖此方法返回更高的优先级(数值越小优先级越高)。

(2) 责任链上下文:MerchantAdminChainContext

  • 该类负责管理责任链的初始化和执行:
    • 在 Spring 容器启动时 (CommandLineRunner),它会扫描实现了 MerchantAdminAbstractChainHandler 接口的所有 Spring Bean**,并根据它们的 mark() 属性将其归类到不同的链条中。
    • 在链条内部,根据 Ordered 的优先级对处理器进行排序。
    • 提供统一的 handler() 方法,根据标识 (Mark) 执行对应的责任链。

(3) 业务服务层:ProductInventoryCheckChainFilter

  • 通过 MerchantAdminChainContext 调用对应的责任链,完成业务参数校验逻辑。
  • 责任链完成校验后,后续可继续执行其他具体的业务逻辑。

责任链的执行流程

借助 MerchantAdminChainContext,上述两个处理器会被自动扫描并加载到责任链中。在运行时,系统会根据 mark()getOrder() 的值,自动按顺序执行它们。

责任链执行流程

五、Java 实现责任链模式 + 策略模式

下面给出一个实现责任链 + 策略模式的完整 Java 示例。

场景:模拟用户请求的审核流程(如普通用户审批、管理员审批、高级管理员审批),并结合不同策略处理请求。

1. 定义处理请求的接口

2. 定义用户请求类

3. 定义不同的策略(处理逻辑)

4. 实现责任链模式的处理者

5. 测试责任链 + 策略模式


六、为何结合使用责任链模式和策略模式?

  1. 流程控制与逻辑定义分离:责任链模式将处理请求的逻辑连接成链,方便动态调整请求传递的流程;策略模式则将处理逻辑封装为独立的策略,可灵活复用和替换,使得流程控制和具体逻辑处理相互独立。
  2. 职责明确分离:责任链模式专注于管理请求的传递,策略模式则聚焦于实现具体的业务逻辑。两者结合使用能让代码结构更加清晰,职责分配更加明确,提高代码的可维护性。
  3. 增强系统灵活性与扩展性:责任链可以动态增删处理者,策略可以动态选择或扩展新的处理逻辑,两者结合大大增强了系统的适配性和扩展性,使系统能够更好地应对不断变化的业务需求。

通过责任链模式与策略模式的结合,能够有效应对复杂的处理流程和多变的业务需求,同时保持代码的简洁性和高内聚的设计结构,为软件开发提供了一种高效的解决方案。

相关推荐
神奇小汤圆1 小时前
没啃透无锁队列,高并发底层你只懂了皮毛!
后端
大鸡腿同学2 小时前
大模型是怎么训练出来的?
后端
lizhongxuan2 小时前
判断一个人懂不懂 agent harness
后端
非洲农业不发达3 小时前
windows终端体验大升级,让你拥有macos级别的美化
前端·后端
妙码生花3 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(十七):登录接口完善,登录页接口整合,解决跨域
前端·后端·ai编程
SamDeepThinking4 小时前
从源码到代码:MyBatis-Flex 与 MyBatis-Plus 的逐项对比
java·后端·程序员
shepherd1114 小时前
一文带你掌握 LLM、Token、Context、Prompt、RAG、MCP、Skill、Agent 等 AI 核心概念
人工智能·后端·ai编程
狂炫冰美式4 小时前
人均配了AI, 为什么公司还是没变快? 🤔 本质还是分布式系统问题
前端·后端·架构