news 2026/5/9 9:27:14

杂记 - 状态模式 VS. 责任链模式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
杂记 - 状态模式 VS. 责任链模式

目录

    • 一、总体对比
    • 二、状态模式
    • 三、责任链模式
    • 四、扩展:手撸Java WebFilter实现

一、总体对比

状态模式和责任链模式都是行为型设计模式,但它们的意图和应用场景不同:

对比项状态模式责任链模式
意图允许对象在内部状态改变时改变它的行为,
看起来就像改变了其类。
使多个对象都有机会处理请求,将这些对象连成一条链,
并沿着这条链传递请求,直到有对象处理它为止。
结构通常有一个上下文(Context)对象和多个状态(State)对象。
上下文持有当前状态的引用,行为委托给当前状态对象。
有一个处理者接口,每个处理者持有下一个处理者的引用。
请求沿链传递,直到被处理。
应用场景对象的行为依赖于它的状态,
并且在运行时可能根据状态变化而改变行为。
有多个对象可以处理同一个请求,
具体由谁处理在运行时决定。
示例工作流引擎、订单状态流转、TCP连接状态。Java Web Filter、日志处理链、审批流。
总结状态模式关注“对象状态的切换”,
每个状态封装一组行为,状态切换时行为也随之切换。
状态模式强调“同一个对象在不同状态下的行为变化”。
责任链模式关注“请求的传递”,
每个处理者决定是否处理请求或传递给下一个处理者。
责任链模式强调“多个对象对同一请求的处理机会”。

二、状态模式

类图:

Client

Context

- state: State

+ request()

«interface»

State

+ handle(Context)

ConcreteStateA

+ handle(Context)

ConcreteStateB

+ handle(Context)

示例代码:

publicinterfaceState{voidhandle(Contextcontext);}publicclassConcreteStateAimplementsState{@Overridepublicvoidhandle(Contextcontext){System.out.println("当前状态:A,切换到B");context.setState(newConcreteStateB());}}publicclassConcreteStateBimplementsState{@Overridepublicvoidhandle(Contextcontext){System.out.println("当前状态:B,切换到A");context.setState(newConcreteStateA());}}publicclassContext{privateStatestate;publicContext(Statestate){this.state=state;}publicvoidsetState(Statestate){this.state=state;}publicvoidrequest(){if(state!=null){state.handle(this);}}}publicclassClient{publicstaticvoidmain(String[]args){Contextcontext=newContext(newConcreteStateA());context.request();// A -> Bcontext.request();// B -> A}}

三、责任链模式

类图:

next

Client

«abstract»

Handler

+setNext(Handler)

+handleRequest(Request)

ConcreteHandlerA

+handleRequest(Request)

ConcreteHandlerB

+handleRequest(Request)

示例代码:

publicabstractclassHandler{protectedHandlernext;publicvoidsetNext(Handlernext){this.next=next;}publicabstractvoidhandleRequest(Stringrequest);}publicclassConcreteHandlerAextendsHandler{@OverridepublicvoidhandleRequest(Stringrequest){if("A".equals(request)){System.out.println("ConcreteHandlerA 处理请求: "+request);}elseif(next!=null){next.handleRequest(request);}else{System.out.println("请求未被处理: "+request);}}}publicclassConcreteHandlerBextendsHandler{@OverridepublicvoidhandleRequest(Stringrequest){if("B".equals(request)){System.out.println("ConcreteHandlerB 处理请求: "+request);}elseif(next!=null){next.handleRequest(request);}else{System.out.println("请求未被处理: "+request);}}}publicclassClient{publicstaticvoidmain(String[]args){HandlerhandlerA=newConcreteHandlerA();HandlerhandlerB=newConcreteHandlerB();handlerA.setNext(handlerB);handlerA.handleRequest("A");// ConcreteHandlerA 处理请求: AhandlerA.handleRequest("B");// ConcreteHandlerB 处理请求: BhandlerA.handleRequest("C");// 请求未被处理: C}}

两者本质区别:
状态模式是“状态驱动行为”,责任链模式是“链式传递请求”。

四、扩展:手撸Java WebFilter实现

Java WebFilter 链式调用的实现原理是基于“责任链模式”(Chain of Responsibility Pattern)。每个 Filter 处理请求后,可以选择继续传递给下一个 Filter 或终止链路。Filter 链由容器(如 Tomcat)维护,依次调用每个 Filter 的 doFilter 方法,最后到达目标 Servlet。

原理简述:

  • 每个 Filter 通过doFilter(ServletRequest, ServletResponse, FilterChain)方法接收请求。
  • FilterChain负责调用下一个 Filter 或最终的 Servlet。
  • 责任链模式:每个处理者(Filter)持有对下一个处理者(FilterChain)的引用。

示例代码:
自定义 Filter 实现:

// MyFilter.javaimportjavax.servlet.*;importjava.io.IOException;publicclassMyFilterimplementsFilter{@OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{// 前置处理System.out.println("MyFilter 前置处理");// 传递给下一个 Filter 或 Servletchain.doFilter(request,response);// 后置处理System.out.println("MyFilter 后置处理");}}

责任链模式简化实现(模拟 FilterChain):

// Filter.javapublicinterfaceFilter{voiddoFilter(Requestrequest,Responseresponse,FilterChainchain);}// FilterChain.javaimportjava.util.List;publicclassFilterChain{privateList<Filter>filters;privateintindex=0;publicFilterChain(List<Filter>filters){this.filters=filters;}publicvoiddoFilter(Requestrequest,Responseresponse){if(index<filters.size()){filters.get(index++).doFilter(request,response,this);}else{// 最终处理(如Servlet)System.out.println("到达最终处理(Servlet)");}}}// Request.java / Response.javapublicclassRequest{}publicclassResponse{}

使用链式调用:

// Main.javaimportjava.util.Arrays;publicclassMain{publicstaticvoidmain(String[]args){Filterfilter1=(req,res,chain)->{System.out.println("Filter1 前置");chain.doFilter(req,res);System.out.println("Filter1 后置");};Filterfilter2=(req,res,chain)->{System.out.println("Filter2 前置");chain.doFilter(req,res);System.out.println("Filter2 后置");};FilterChainchain=newFilterChain(Arrays.asList(filter1,filter2));chain.doFilter(newRequest(),newResponse());}}

输出示例:

Filter1 前置 Filter2 前置 到达最终处理(Servlet) Filter2 后置 Filter1 后置

总结:

  • Filter 链式调用本质是责任链模式的应用。
  • 每个 Filter 处理完后通过chain.doFilter传递给下一个 Filter 或最终 Servlet。
  • 这样实现了请求处理的灵活扩展和解耦。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 11:03:18

双碳目标下综合能源系统低碳运行优化调度Matlab实现

双碳目标下综合能源系统低碳运行优化调度Matlab程序 包含光伏、风电、热电联产、燃气锅炉、电锅炉、电储能、碳捕集设备&#xff0c;考虑碳交易 以系统运行成本最小为目标函数 采用Yalmip&#xff0b;Cplex求解在双碳目标的大背景下&#xff0c;综合能源系统的低碳运行优化调度…

作者头像 李华
网站建设 2026/5/3 3:32:14

springboot+vue校园二手闲置物品拍卖系统 人脸识别

目录摘要开发技术核心代码参考示例1.建立用户稀疏矩阵&#xff0c;用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度总结源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;摘要 校园二手闲置物品拍卖系统结合SpringBoo…

作者头像 李华
网站建设 2026/5/4 6:32:32

计算机毕业设计,基于springboot的房屋租赁管理系统,附源码+数据库+论文,包远程安装调试运行

1、项目介绍 本文从用户的功能要求出发&#xff0c;建立了房屋租赁系统&#xff0c;系统中的功能模块主要是实现人中心、房屋类型管理、房屋信息、预约看房管理、合同信息管理、房屋报修管理、房屋评价管理、我要当房东管理、留言板管理、系统管理等功能部分&#xff1b;经过认…

作者头像 李华
网站建设 2026/5/7 11:06:17

计算机毕业设计,基于springboot的高校心理教育辅导系统,附源码+数据库+论文+开题,包远程安装调试运行

1、项目介绍 此高校心理教育辅导系统功能分析主要分为管理员功能模块、教师功能模块和学生功能模块三大模块&#xff0c;下面详细介绍这三大模块的主要功能&#xff1a; &#xff08;1&#xff09;管理员&#xff1a;管理员登陆后可对系统进行全面管理&#xff0c;管理员主要…

作者头像 李华