目录

1、状态模式

1.1、介绍

1.2、设计背景

1.3、适用场景

2、实现

2.1、if-else实现

2.2、状态模式实现

2.3、最终版

1、关于if-else的优化

2、状态模式下的优化

3、ArrayList 配置“状态流”

3、总结


前言

关于Java的设计模式分类如下:

对于状态模式的组件组成,如下所示:


1、状态模式

1.1、介绍

允许一个对象在其内部状态发生改变时,行为也随之改变,看起来就像对象修改了它的类。

  • 状态模式就是把“状态”封装成独立的类,不同状态下执行不同的逻辑
  • 状态切换由对象自己控制,而不是外部用 if-else/switch来判断

1.2、设计背景

问题场景:

if (status == "UNPAID") { /* 处理支付 */ }
else if (status == "PAID") { /* 处理发货 */ }
else if (status == "SHIPPED") { /* 处理收货 */ }
  • 每加一个状态,要修改这段代码
  • 状态切换逻辑和行为混在一起,难维护

状态模式的好处:

  • 每个状态的逻辑单独放在一个类中
  • 遵循 开闭原则(新增状态只加类,不改原来代码)
  • 状态的切换由对象自身控制,不依赖外部复杂判断

两者对比,如下所示:

1.3、适用场景

在项目中常用的场景如下:

  • Spring StateMachine(状态机框架)
  • 订单系统:未支付 → 已支付 → 已发货 → 已完成
  • 工作流引擎(Flowable、Activiti)
  • Netty Channel 状态:UNREGISTERED → REGISTERED → ACTIVE → INACTIVE

💡 因此:

  • 如果状态很少且不会变,可以用 if-else
  • 如果状态多、变化频繁,并且有复杂行为 => 用状态模式

2、实现

2.1、if-else实现

public class Order {public static final int UNPAID = 0;public static final int PAID = 1;public static final int SHIPPED = 2;public static final int DONE = 3;private int status = UNPAID;public void process() {if (status == UNPAID) {System.out.println("当前订单未支付,执行支付逻辑...");status = PAID;} else if (status == PAID) {System.out.println("订单已支付,执行发货逻辑...");status = SHIPPED;} else if (status == SHIPPED) {System.out.println("订单已发货,执行收货逻辑...");status = DONE;} else if (status == DONE) {System.out.println("订单已完成");} else {System.out.println("未知订单状态");}}
}

测试:

public class Test {public static void main(String[] args) {Order order = new Order();order.process(); // 支付order.process(); // 发货order.process(); // 收货order.process(); // 已完成}
}

这种方式短期内可用,但问题比较明显:

1、集中式 if-else

所有状态逻辑都在一个方法里面,方法不断膨胀,维护困难。

2、违反开闭原则

新增状态时必须修改这个方法的代码,容易引入 bug。

3、状态切换逻辑分散

可能在多个方法都有类似的 if-else,改动的时候要到处找。

4、可读性差

状态和行为耦合得很紧,不直观。

2.2、状态模式实现

订单状态流转

1、定义状态接口

public interface OrderState {void handle(OrderContext context);
}

2、具体状态类

public class UnpaidState implements OrderState {public void handle(OrderContext context) {System.out.println("当前订单未支付,执行支付逻辑...");context.setState(new PaidState()); // 切换状态}
}public class PaidState implements OrderState {public void handle(OrderContext context) {System.out.println("订单已支付,执行发货逻辑...");context.setState(new ShippedState());}
}public class ShippedState implements OrderState {public void handle(OrderContext context) {System.out.println("订单已发货,执行收货逻辑...");context.setState(new DoneState());}
}public class DoneState implements OrderState {public void handle(OrderContext context) {System.out.println("订单已完成");}
}

3、环境类

public class OrderContext {private OrderState state;public OrderContext(OrderState state) { this.state = state; }public void setState(OrderState state) { this.state = state; }public void request() { state.handle(this); }
}

测试

public class Test {public static void main(String[] args) {OrderContext order = new OrderContext(new UnpaidState());order.request(); // 支付order.request(); // 发货order.request(); // 收货order.request(); // 已完成}
}输出:
当前订单未支付,执行支付逻辑...
订单已支付,执行发货逻辑...
订单已发货,执行收货逻辑...
订单已完成

基于前面的if-else和状态模式都需要多次去调用方法,因此可以对调用次数进行优化。

2.3、最终版

1、关于if-else的优化

public class Order {private int status = 0;private static final List<Integer> PROCESS_LIST = List.of(0, // UNPAID1, // PAID2, // SHIPPED3  // DONE);public void process() {if (status == 0) {System.out.println("未支付 -> 支付");status = 1;} else if (status == 1) {System.out.println("已支付 -> 发货");status = 2;} else if (status == 2) {System.out.println("已发货 -> 收货");status = 3;} else {System.out.println("订单完成");}}public static void main(String[] args) {Order order = new Order();PROCESS_LIST.forEach(s -> order.process());}
}

这样避免了写 4 行 order.process(),但 逻辑依旧集中在一个方法里,只是调用更“批量”了。

2、状态模式下的优化

状态模式下,我们可以更灵活地用集合来管理状态流转过程,而且不用去写 if-else。

例子:

interface State {void handle(OrderContext ctx);
}class UnpaidState implements State {public void handle(OrderContext ctx) {System.out.println("当前订单未支付 -> 执行支付逻辑...");ctx.setState(new PaidState());}
}class PaidState implements State {public void handle(OrderContext ctx) {System.out.println("订单已支付 -> 执行发货逻辑...");ctx.setState(new ShippedState());}
}class ShippedState implements State {public void handle(OrderContext ctx) {System.out.println("订单已发货 -> 执行收货逻辑...");ctx.setState(new DoneState());}
}class DoneState implements State {public void handle(OrderContext ctx) {System.out.println("订单已完成");}
}class OrderContext {private State state;public OrderContext(State state) {this.state = state;}public void setState(State state) {this.state = state;}public void process() {state.handle(this);}
}

驱动代码:用集合 + 循环执行

public class TestOrder {public static void main(String[] args) {OrderContext order = new OrderContext(new UnpaidState());// 一直循环直到状态是 DoneStatewhile (!(order.state instanceof DoneState)) {order.process();}// 最后一遍处理完成状态order.process();}
}

特点

  • 不用写多行 request(),直接用循环驱动
  • 如果状态机变长/变短,不影响调用逻辑
  • 也可以设计一个 List 状态链 提前加载好,遍历一次性跑完

3、ArrayList 配置“状态流”

状态模式也可以结合 状态数组

List<State> flow = List.of(new UnpaidState(),new PaidState(),new ShippedState(),new DoneState()
);OrderContext ctx = new OrderContext(flow.get(0));
for (State state : flow) {ctx.setState(state);ctx.process();
}
  • 优势:业务状态流程可以从配置文件甚至数据库加载,不用改代码
  • 实现可拥抱灵活性,比如读取“审批流”、“工单流”这些可配置流程


3、总结

如下所示:


总结

        状态模式是一种行为型设计模式,允许对象在内部状态改变时改变其行为。模式中包含上下文抽象状态具体状态角色。

        优点包括解耦客户端和状态对象,可扩展性强,避免大量条件语句。缺点是可能增加系统类的数量和复杂性。适用场景如自动售货机的状态转换、线程状态管理等。


参考文章:

1、设计模式第21讲——状态模式(State)-CSDN博客文章浏览阅读6.7k次,点赞22次,收藏104次。状态模式是一种行为型设计模式,允许对象在内部状态改变时改变其行为。模式中包含上下文、抽象状态和具体状态角色。优点包括解耦客户端和状态对象,可扩展性强,避免大量条件语句。缺点是可能增加系统类的数量和复杂性。适用场景如自动售货机的状态转换、线程状态管理等。代码示例展示了自动售卖机如何利用状态模式实现不同状态的切换。 https://blog.csdn.net/weixin_45433817/article/details/131521862?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522d157caaef17e4af5a1ebe4b41acb1286%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=d157caaef17e4af5a1ebe4b41acb1286&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-131521862-null-null.142^v102^control&utm_term=%E7%8A%B6%E6%80%81%E6%A8%A1%E5%BC%8F&spm=1018.2226.3001.4187

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/96892.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/96892.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/96892.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

three.js+WebGL踩坑经验合集(9.2):polygonOffsetFactor工作原理大揭秘

本篇延续上篇内容&#xff1a; three.jsWebGL踩坑经验合集(9.1):polygonOffsetUnits工作原理大揭秘-CSDN博客 跟polygonOffsetUnits相比&#xff0c;polygonOffsetFactor的系数m要复杂得多&#xff0c;因为它跟平面的视角相关&#xff0c;而不像r那样&#xff0c;在一个固定的…

C++高级特性与设计模式答案

目录 C++高级特性与设计模式:从资源管理到架构设计 一、C++高级特性:超越基础语法的利器 1. 什么是RAII(资源获取即初始化)?它有什么作用? 实现原理 核心作用 2. 什么是Pimpl惯用法?它有什么优势? 实现方式 核心优势 3. 什么是CRTP(奇异递归模板模式)?它的应用场景是…

论文阅读:arxiv 2025 Can You Trick the Grader? Adversarial Persuasion of LLM Judges

总目录 大模型安全相关研究&#xff1a;https://blog.csdn.net/WhiffeYF/article/details/142132328 Can You Trick the Grader? Adversarial Persuasion of LLM Judges https://arxiv.org/pdf/2508.07805 https://www.doubao.com/chat/17534937260220418 文章目录论文翻译…

6pen Art

本文转载自&#xff1a;6pen Art - Hello123工具导航 ** 一、&#x1f3a8; 6pen 是什么&#xff1f; 6pen 是一款由国内团队开发的 AI 绘画工具&#xff0c;让你只需用文字描述想法&#xff0c;就能瞬间生成惊艳的视觉画作。不管是写实风景还是抽象概念&#xff0c;它都能理…

Let‘s Encrypt证书在 Android5.x 的设备上报错

报错信息&#xff1a; com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.at com.android.volley.toolbox.NetworkUtility.shouldRetryException(N…

C语言数组名与sizeof的深层关联

要理解 “数组名本质代表整个数组的类型和内存块” 与 “sizeof(arr) 输出总字节数” 的关联&#xff0c;核心是抓住 sizeof 运算符的设计逻辑 和 数组类型的本质属性—— 这两者是直接挂钩的&#xff0c;我们一步步拆解&#xff1a;第一步&#xff1a;先明确 sizeof 的核心作用…

最近对javashop做了压力测试:百万级并发下完全不是问题

最近对 javashop 做了压力测试&#xff1a;百万级并发下完全不是问题 在电商行业竞争白热化的今天&#xff0c;系统性能直接决定了用户体验和企业商业成功。本文基于《Javashop 压测报告》&#xff0c;从技术架构、核心指标、业务价值三大维度深度解析其性能优势&#xff0c;并…

Java大厂面试实战:从Spring Boot到微服务架构的全链路技术解析

Java大厂面试实战&#xff1a;从Spring Boot到微服务架构的全链路技术解析 面试场景&#xff1a;某互联网大厂Java后端开发岗 面试官&#xff08;严肃&#xff09;&#xff1a;谢飞机&#xff0c;我们今天来聊点硬核的。先说说你对Java生态的理解。 谢飞机&#xff08;挠头&…

在分布式环境下正确使用MyBatis二级缓存

在分布式环境下使用 MyBatis 二级缓存&#xff0c;核心挑战是解决多节点缓存一致性问题。单机环境中&#xff0c;二级缓存是内存级别的本地缓存&#xff0c;而分布式环境下多节点独立部署&#xff0c;本地缓存无法跨节点共享&#xff0c;易导致 “缓存孤岛” 和数据不一致。本文…

血缘元数据采集开放标准:OpenLineage Integrations Apache Spark Quickstart with Jupyter

OpenLineage 是一个用于元数据和血缘采集的开放标准&#xff0c;专为在作业运行时动态采集数据而设计。它通过统一的命名策略定义了由作业&#xff08;Job&#xff09;、运行实例&#xff08;Run&#xff09;和数据集&#xff08;Dataset&#xff09; 组成的通用模型&#xff0…

人工智能之数学基础:离散随机变量和连续随机变量

本文重点 随机变量是概率论与统计学中的核心概念,用于将随机现象的抽象结果转化为可量化的数值。根据取值特性的不同,随机变量可分为离散型和连续型两大类。 在前面的课程中我们学习了随机变量,随机变量可以理解为一个函数,通过这个函数我们就可以将随机试验中的结果数值…

SQL语句(查询)

单表查询 常量查询 让我们来看一个具体的 SQL 代码和结果示例&#xff0c;假设有一张名为 orders 的数据表&#xff0c;它存储了订单信息&#xff0c;包括订单编号&#xff08;order_id&#xff09;、商品单价&#xff08;unit_price&#xff09;、购买数量&#xff08;quantit…

Java 大视界 -- Java 大数据机器学习模型在金融市场波动预测与资产配置动态调整中的应用

Java 大视界 -- Java 大数据机器学习模型在金融市场波动预测与资产配置动态调整中的应用引言&#xff1a;正文&#xff1a;一、Java 构建的金融数据处理架构1.1 多源数据实时融合与清洗1.2 跨市场数据关联&#xff08;风险传导分析&#xff09;二、Java 驱动的市场波动预测模型…

基于muduo库的图床云共享存储项目(一)

基于muduo库的图床云共享存储项目&#xff08;一&#xff09;项目简介整体架构项目依赖基础组件muduo库Channel类Poller / EpollPoller 类EventLoopAcceptor类FastDfsJSON的使用项目简介 当前所实现的项目是一个基于muduo库的图床云共享存储项目&#xff0c;他的主要的功能就是…

数字化转型三阶段:从信息化、数字化到数智化的战略进化

企业的数字化转型包括信息化、数字化、数智化三个阶段&#xff0c;并非一个阶段结束才能进入到下一个阶段。01信息化→业务数据化信息化是将企业在生产经营过程中产生的业务信息进行记录、储存和管理&#xff0c;通过电子终端呈现&#xff0c;便于信息的传播与沟通。信息化是对…

SpringBoot如何获取系统Controller名称和方法名称

这种代码里面的Controller和里面的方法怎么获取代码&#xff1a;/*** 获取所有Controller名称*/ApiDescription("获取所有Controller名称")PostMapping("/getControllerNames")public Result getControllerNames() {return dataDesensitizationRulesServic…

(二十二)深入了解AVFoundation-编辑:视频变速功能-实战在Demo中实现视频变速

一. 引言视频变速&#xff08;Speed Ramp&#xff09;是视频编辑中最常见的特效之一&#xff1a;慢动作&#xff08;Slow Motion&#xff09;&#xff1a;强调细节&#xff0c;让观众捕捉到肉眼难以察觉的瞬间&#xff1b;快动作&#xff08;Fast Motion&#xff09;&#xff1…

MCP零基础学习(7)|实战指南:构建论文分析智能体

在之前的教程中&#xff0c;我们已经介绍了 MCP&#xff08;Model Context Protocol&#xff09;的基本概念及其核心组件。在本篇教程中&#xff0c;我们将通过一个实际案例&#xff0c;演示如何运用 MCP 构建一个能够分析学术论文的智能体。这个智能体将具备读取 PDF 文件、提…

Unity URP半透明物体自身交叠解决方案

前言 在 Unity 的通用渲染管线&#xff08;URP&#xff09;中&#xff0c;处理半透明物体的自身交叠是一个常见挑战。当半透明物体&#xff08;如玻璃、水或透明材质&#xff09;的某些部分相互重叠时&#xff0c;可能会出现渲染顺序问题&#xff0c;导致视觉瑕疵。 对惹&…

哈希算法入门:深入浅出讲明白HASH哈希算法

一、先搞懂&#xff1a;哈希算法到底是 “啥玩意儿”&#xff1f;咱们先别碰复杂概念&#xff0c;从你每天都会遇到的事说起 —— 你会发现&#xff0c;“哈希思维” 其实早就藏在生活里了。&#xff08;一&#xff09;生活中的 “哈希例子”&#xff1a;给东西 “贴标签、找位…