Java责任链模式案例

wen java案例 4

Java责任链模式实战:从审批流到中间件,一文搞懂解耦艺术


目录导读(Table of Contents)

  1. 责任链模式是什么? —— 核心概念与生活隐喻
  2. 四大角色拆解 —— Handler、ConcreteHandler、Client的协作密码
  3. Java代码实战 —— 从零搭建一个订单风控审批链
  4. 真实场景案例 —— Spring MVC拦截器与Netty Pipeline的底层逻辑
  5. 高频面试问答 —— 破解“如何避免链断裂”等致命追问
  6. 模式对比与坑点 —— 责任链 vs 策略模式 vs 装饰器模式

责任链模式是什么?—— 核心概念与生活隐喻

想象一个“客服工单系统”:普通问题由一线客服处理,技术问题升级给工程师,重大事故则直达总监,每个处理者接到请求后,要么自己处理,要么传递给下一级——这就是责任链的生活化映射

Java责任链模式案例

官方定义:避免请求发送者与接收者耦合,让多个对象都有机会处理请求,将这些对象连成一条链,并沿着链传递请求,直到有一个对象处理它为止。

核心价值:发送者无需知道谁最终处理,实现请求者与处理者的完全解耦,相比if-else嵌套,责任链的扩展只需新增节点,符合开闭原则


四大角色拆解

角色 职责 关键点
Handler(抽象处理者) 定义处理接口,持有后继引用 通常包含setNext()handleRequest()
ConcreteHandler(具体处理者) 判断能否处理,否则转发 每个节点只关心自己的逻辑
Client(客户端) 组装链并发送请求 需手动构建链的先后顺序
Request(请求对象) 封装数据与上下文 可携带变量用于条件判断

关键设计:抽象类中维护nextHandler,用setNext方法串联,确保所有节点遵循同一传递协议。


Java代码实战—— 从零搭建订单风控审批链

场景:电商订单金额>1000需经理审批,>5000需总监审批,>10000需CEO审批。

// 1. 抽象处理者
public abstract class Approver {
    protected Approver next;
    public void setNext(Approver next) { this.next = next; }
    public abstract void process(Order order);
}
// 2. 具体处理者 - 经理
public class Manager extends Approver {
    public void process(Order order) {
        if (order.getAmount() <= 1000) {
            System.out.println("经理审批通过");
        } else if (next != null) {
            next.process(order); // 关键:转发
        }
    }
}
// 3. 具体处理者 - 总监(逻辑类似,判断金额<=5000)
// 4. 具体处理者 - CEO(判断金额>10000)
// 5. 客户端组装
public class Client {
    public static void main(String[] args) {
        Approver manager = new Manager();
        Approver director = new Director();
        Approver ceo = new CEO();
        manager.setNext(director);
        director.setNext(ceo);
        manager.process(new Order(8000)); // 输出:总监审批通过
    }
}

运行逻辑:请求沿链流动,第一个满足条件的节点直接处理并终止,未处理则传给后继。


真实场景案例—— 框架中的责任链灵魂

Spring MVC的HandlerInterceptor

// 多个拦截器按注册顺序执行
preHandle() 返回false则中断链,类似“短路”

Spring用HandlerExecutionChain维护拦截器列表,按顺序调用,实现登录校验、日志记录等横切关注点。

Netty的ChannelPipeline

  • 入站事件(Inbound)按head→tail传播,出站(Outbound)反向传播
  • 每个ChannelHandler就是责任链节点,通过ctx.fireChannelRead()传递

Tomcat的FilterChain

// 过滤器链:doFilter()方法调用chain.doFilter()放行
// 停止调用链则响应被拦截

高频面试问答—— 破解“致命追问”

Q1:如果链上所有节点都不处理怎么办?

最佳实践:在链的尾部追加一个默认处理节点(如DefaultHandler),兜底抛出异常或记录日志,避免静默失败。

Q2:如何动态调整链的顺序?

使用List管理节点,通过@Order注解或配置文件控制顺序,例如Spring的FilterRegistrationBean可以动态设置URL映射和顺序。

Q3:责任链模式有哪些变体?

  • 纯责任链:一个请求被一个节点处理,必须明确处理
  • 不纯责任链:允许请求被多个节点处理(如日志过滤器)
  • 环状链:链尾指向链头,适合轮询

Q4:与策略模式的区别?

策略模式选择单一算法替换,责任链是多个处理者排队,策略是“如何做”,责任链是“谁来做”。


模式对比与坑点—— 资深架构师的避坑指南

对比维度 责任链 策略模式 装饰器模式
意图 请求传递,多处理者 算法替换 增强功能
链接方式 内部持有后继 客户端选择 包装器嵌套
终止条件 可中断传递 一次执行 递归调用
经典示例 审批流、过滤器 压缩算法 IO流BufferedReader

致命坑点

  1. 循环引用:避免setNext指向自身或构成环,导致死循环
  2. 顺序敏感:若节点依赖前序处理后的状态,需确保顺序正确(如先鉴权后限流)
  3. 性能损耗:链路过长时,每次请求都遍历,考虑用break条件提前中断

责任链模式是Java世界中“优雅解耦”的典范,从Spring拦截器到Netty管道,它让复杂请求的流转变得清晰可控,掌握它,你的代码将更具弹性,面试时也能从容应对,不妨重构一段臃肿的if-else逻辑,感受链式思维的魅力吧!

抱歉,评论功能暂时关闭!