资讯详情

职责链模式详解:让请求在链上流动,谁该处理谁处理(含可运行代码 + 纯/不纯辨析)

📅 2026/10/7 7:22:08 | 华诺云谱 👁 阅读
职责链模式详解:让请求在链上流动,谁该处理谁处理(含可运行代码 + 纯/不纯辨析)
一、职责链模式是什么职责链模式构造一系列分担不同职责的对象这些对象像链条一样紧密相连共同完成一个任务。请求在链上传递链上的每个对象都有机会处理它。核心思想解耦发送请求者和处理请求者——发送者只把请求丢给链头不用知道是谁、经过谁最终处理的。分类行为型模式关注对象之间如何分工协作、职责如何传递。经典例子Servlet 的 Filter 链、审批流、日志拦截器。“构造一系列分担不同职责的类的对象来共同完成一个任务”这正是它的定义。二、为什么需要职责链模式动机假设要处理一个请求逻辑是能处理的就处理处理不了的往上交。如果不职责链if(金额5000)经理批;elseif(金额20000)总监批;elseCEO批;痛点处理规则写死在调用方每增加一级审批就要改调用方代码违背了开闭原则而且调用方必须知道所有处理者的存在和顺序。职责链把这些处理者串成链调用方只chain.handle()谁处理、怎么排全在链内部互不影响。三、职责链模式的结构角色和职责角色职责Handler抽象处理者定义处理请求的接口持有下一个处理者的引用successorConcreteHandler具体处理者实现处理逻辑能处理就处理不能处理就转给 successor类图mermaidsuccessor(下一个)CarHandler#CarHandler successorsetNextHandler(CarHandler) : CarHandlerHandlerCar()CarHeadHandlerCarBodyHandlerCarTailHandler关键点每个Handler自己持有successor下一个链是每个节点指向后一个的单向链表。四、代码举例汽车组装链// 1. 抽象处理者持有下一个处理者publicabstractclassCarHandler{protectedCarHandlersuccessor;// 下一个处理节点// 设置下一个节点返回被设置的节点便于链式串联publicCarHandlersetNextHandler(CarHandlersuccessor){this.successorsuccessor;returnsuccessor;}publicabstractvoidHandlerCar();}// 2. 具体处理者车头publicclassCarHeadHandlerextendsCarHandler{publicvoidHandlerCar(){System.out.println(组装车头);if(this.successor!null)this.successor.HandlerCar();// 传递给下一个}}// 3. 具体处理者车身publicclassCarBodyHandlerextendsCarHandler{publicvoidHandlerCar(){System.out.println(组装车身);if(this.successor!null)this.successor.HandlerCar();}}// 4. 具体处理者车尾publicclassCarTailHandlerextendsCarHandler{publicvoidHandlerCar(){System.out.println(组装车尾);if(this.successor!null)this.successor.HandlerCar();}}// 5. 客户端publicclassMainClass{publicstaticvoidmain(String[]args){CarHandlerheadHnewCarHeadHandler();CarHandlerbodyHnewCarBodyHandler();CarHandlertailHnewCarTailHandler();// 正确链式串联setNextHandler 返回被设置的下一个headH.setNextHandler(bodyH).setNextHandler(tailH);headH.HandlerCar();// 只调链头链自动依次执行}}运行结果组装车头 组装车身 组装车尾五、核心辨析纯职责链 vs 不纯职责链汽车组装例子每个节点都执行再传给下一个——这叫不纯职责链过滤链。职责链还有另一半纯职责链——某个节点处理完就终止不再往下传。维度不纯职责链过滤链纯职责链行为每个节点都处理再传给下一个某节点处理完即终止不继续传是否必达末尾是除非异常中断否中途可停典型场景Servlet Filter、日志/AOP 拦截、组装流水线审批流、异常处理、路由分发本例车头/车身/车尾全组装审批只要一级通过即停纯职责链示例审批流abstractclassApprover{protectedApproversuccessor;publicApproversetNext(Approvers){this.successors;returns;}publicabstractvoidapprove(intamount);}classManagerextendsApprover{// 经理5000publicvoidapprove(intamount){if(amount5000)System.out.println(经理审批通过amount);elseif(successor!null)successor.approve(amount);// 超权限转上级elseSystem.out.println(无人能审批amount);}}classDirectorextendsApprover{// 总监20000publicvoidapprove(intamount){if(amount20000)System.out.println(总监审批通过amount);elseif(successor!null)successor.approve(amount);elseSystem.out.println(无人能审批amount);}}classCEOextendsApprover{// CEO兜底publicvoidapprove(intamount){System.out.println(CEO 审批通过amount);}}// 使用ManagermnewManager();DirectordnewDirector();CEOcnewCEO();m.setNext(d).setNext(c);m.approve(30000);// 经理不批 → 总监不批 → CEO 批中途未中断错误approve(30000)输出CEO 审批通过——请求一路上交直到能处理的节点为止这正是不纯与纯职责链最直观的区别。六、真实世界中的职责链模式JDK / 框架ServletFilter链FilterChain.doFilter()依次调用每个Filter每个 Filter 处理完调chain.doFilter()传给下一个——典型的不纯职责链Spring 的HandlerInterceptor同理。OKHttpInterceptor网络请求拦截器链日志、重试、缓存、桥接每个 Interceptor 处理一部分再chain.proceed()和 Servlet Filter 同构。MyBatisPlugin拦截器基于责任链 动态代理把多个插件串成链依次增强Executor/StatementHandler等。TomcatPipeline-Valve、NettyChannelPipeline底层都是请求在Valve/Handler链上流动。Java 异常机制广义catch块按声明顺序匹配命中即处理并终止——纯职责链的影子。七、优缺点优点解耦发送者与接收者调用方不依赖具体处理类降低耦合。符合开闭原则新增处理节点只需挂到链上不改已有代码。灵活链的顺序、增删节点可动态配置如 Spring 的Order。缺点调试困难请求在链上跳调用栈深出问题时不易定位是哪个节点处理的。可能漏处理若链尾都没人处理请求就石沉大海需设默认兜底节点如审批流的 CEO。性能请求要遍历链链过长时有一定开销原笔记可能会影响处理速度即指此。选型口诀“一个请求要过好几道关、且谁处理不确定 ⇒ 用职责链处理者固定且单一 ⇒ 直接调用即可。”八、总结职责链 把处理者串成链请求沿链传递能处理就处理或增强后继续传发送者与处理者解耦。记住两种形态不纯链每个都处理如 Filter——纯链处理即停如审批。链构建注意setNext的返回语义避免原文嵌套调用跳过节点的坑。一句话收尾职责链模式是请求的击鼓传花——传到谁手里谁处理处理完看情况接着传或停下。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑