news 2026/4/23 12:12:56

杂记 - 状态模式 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/4/9 19:17:30

playwright工具(一)自动打开浏览器

playwright1、介绍Playwright 是一个由 Microsoft 开源的 端到端&#xff08;E2E&#xff09;自动化测试工具&#xff0c;主要用于测试 Web 应用。2、作用自动化测试 Chromium / Firefox / WebKit支持 多语言JavaScript / TypeScriptJavaPythonC#可用于&#xff1a;UI 自动化测…

作者头像 李华
网站建设 2026/4/16 17:27:32

面向多端部署的社区平台技术方案:uniapp 与java微服务架构的工程化实践

在内容平台逐渐走向垂直化与私域化的趋势下&#xff0c;企业在规划社区类产品时&#xff0c;往往不再只关注功能是否齐全&#xff0c;而是更关心系统是否易扩展、可维护、能长期演进。 尤其是当目标产品形态同时覆盖 APP 与小程序&#xff0c;并具备内容、社交、电商与即时通讯…

作者头像 李华
网站建设 2026/4/23 5:33:34

别再花冤枉钱!免费 SSL/HTTPS 证书全攻略来袭

一、SSL 证书知多少在如今网络时代&#xff0c;SSL 证书可是保护数据安全的 “盾牌”。它通过加密传输&#xff0c;让网站与用户间信息往来不被窃取、篡改&#xff0c;有效抵御网络攻击。这就引出咱们的主角 —— 免费 SSL 证书。二、免费 SSL 证书优势加密强&#xff1a;为网站…

作者头像 李华
网站建设 2026/4/23 9:45:45

2026必备!本科生毕业论文AI论文软件TOP10测评

2026必备&#xff01;本科生毕业论文AI论文软件TOP10测评 2026年本科生论文写作工具测评&#xff1a;为何需要这份榜单&#xff1f; 随着人工智能技术的不断进步&#xff0c;越来越多的本科生开始借助AI论文软件提升写作效率与质量。然而&#xff0c;面对市场上琳琅满目的工具&…

作者头像 李华
网站建设 2026/4/23 9:46:36

java协同过滤算法的外卖商城互助平台vue

目录协同过滤算法概述系统架构设计核心功能模块技术实现细节应用价值开发技术核心代码参考示例1.建立用户稀疏矩阵&#xff0c;用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度总结源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式…

作者头像 李华