【设计模式】三十一、状态模式
系列文章|源码
https://github.com/tyronczt/design-mode-learn
文章目录
- 系列文章|源码
- 一、模式核心思想
- 二、模式结构
- 三、Java代码示例:订单状态管理
- 1. 定义状态接口
- 2. 实现具体状态类
- 3. 上下文类(Context)
- 4. 客户端调用
- 5. 运行截图
- 四、状态模式的核心优势
- 1. 消除复杂条件分支
- 2. 高扩展性与维护性
- 3. 符合开闭原则(OCP)
- 4. 状态转换显式化
- 5. 提升代码复用性
- 五、适用场景
- 六、与其他模式的协作
- 七、总结
- 参考
一、模式核心思想
状态模式(State Pattern)是一种行为型设计模式,允许对象在其内部状态改变时改变自身行为。其核心思想是将对象的状态抽象为独立类,通过委托状态对象处理与状态相关的逻辑,从而消除复杂的条件判断语句(如if-else或switch-case),提升代码的可维护性和扩展性。
二、模式结构
状态模式包含三个核心角色:
| 角色 | 职责 | Java实现示例 |
|---|---|---|
| Context(上下文) | 维护当前状态对象的引用,并将状态相关操作委托给具体状态类 | 持有State接口实例,提供状态切换方法(如setState()) |
| State(状态接口) | 定义状态行为的抽象方法,约束具体状态类的实现 | 接口或抽象类(如OrderState接口定义handleState()方法) |
| ConcreteState(具体状态) | 实现特定状态下的行为逻辑,并触发状态转换 | 实现State接口的类(如PayOrder处理支付状态逻辑) |

三、Java代码示例:订单状态管理
以下是一个简化的订单状态流转示例,展示状态模式的实际应用:
1. 定义状态接口
public interface IOrderState {/*** 处理订单上下文*/void handle(OrderContext context);
}
2. 实现具体状态类
// 待支付状态
public class PendingPaymentState implements IOrderState {// 实现接口中的handle方法@Overridepublic void handle(OrderContext context) {System.out.println("订单待支付,跳转支付页面...");context.setState(new PaidState()); // 状态切换}
}// 已支付状态
public class PaidState implements IOrderState {@Overridepublic void handle(OrderContext context) {System.out.println("订单已支付,准备发货...");context.setState(new ShippedState());}
}// 已发货状态
public class ShippedState implements IOrderState {@Overridepublic void handle(OrderContext context) {System.out.println("订单已发货,待收货...");}
}
3. 上下文类(Context)
public class OrderContext {private IOrderState state;public void setState(IOrderState state) {this.state = state;}public void process() {state.handle(this);}
}
4. 客户端调用
public class Client {public static void main(String[] args) {// 创建一个订单上下文实例OrderContext order = new OrderContext();// 设置订单的初始状态为待支付order.setState(new PendingPaymentState());order.process(); // 输出:订单待支付,跳转支付页面...order.process(); // 输出:订单已支付,准备发货...order.process(); // 输出:订单已发货,待收货...}
}
5. 运行截图

四、状态模式的核心优势
1. 消除复杂条件分支
• 问题:传统方式需通过大量if-else判断当前状态(如订单状态),代码臃肿且难以维护。
• 解决:每个状态封装独立类,逻辑清晰(如PendingState仅处理待支付逻辑)。
2. 高扩展性与维护性
• 新增状态:只需添加新状态类(如新增CanceledState),无需修改现有代码。
• 修改行为:仅需调整对应状态类的逻辑,避免牵一发而动全身。
3. 符合开闭原则(OCP)
• 对扩展开放:新状态不影响原有系统。
• 对修改关闭:上下文类无需因状态增减而改动。
4. 状态转换显式化
• 状态流转由具体状态类控制(如PaidState触发向ShippedState的转换),逻辑集中且透明。
5. 提升代码复用性
• 公共逻辑可抽取至抽象类(如状态切换的公共方法),减少重复代码。
五、适用场景
- 多状态对象:如订单状态(待支付/已发货)、任务状态(进行中/已完成)。
- 行为依赖状态:如游戏角色状态(攻击/防御)触发不同动作。
- 需动态切换逻辑:如电梯运行状态(上行/停止)对应不同控制规则。
六、与其他模式的协作
• 策略模式:状态模式强调状态驱动行为,策略模式侧重算法选择(如加密算法切换)。
• 观察者模式:结合使用可实现状态变更实时通知(如订单状态更新触发邮件通知)。
七、总结
状态模式通过解耦状态与行为,解决了复杂状态逻辑的维护难题。其优势在Java中尤为突出,结合接口和多态特性,能高效实现灵活的状态管理。实际开发中,建议在状态较多或流转复杂的场景(如电商、游戏)优先采用此模式。
项目代码:https://github.com/tyronczt/design-mode-learn/tree/main/design-mode-learn-31
参考
7.状态设计模式 - 掘金
状态设计模式
相关文章:
【设计模式】三十一、状态模式
系列文章|源码 https://github.com/tyronczt/design-mode-learn 文章目录 系列文章|源码一、模式核心思想二、模式结构三、Java代码示例:订单状态管理1. 定义状态接口2. 实现具体状态类3. 上下文类(Context)4. 客户端调用5. 运行截图 四、状…...
vue 获取当前时间并自动刷新
新增需求,需要在大屏的右上角展示当前时间,并实时按秒刷新,通过通义千问搜索关键js代码后,整理出如下代码。 【效果图】 【HTML】 <div class"time-wrap">{{ formattedDateTime }}<span> {{ weekTime }}&…...
C 语 言 --- 扫 雷 游 戏(初 阶 版)
C 语 言 --- 扫 雷 游 戏 初 阶 版 代 码 全 貌 与 功 能 介 绍扫雷游戏的功能说明游 戏 效 果 展 示游 戏 代 码 详 解game.htest.cgame.c 总结 💻作 者 简 介:曾 与 你 一 样 迷 茫,现 以 经 验 助 你 入 门 C 语 言 💡个 人 主…...
WebDeveloper靶机详解
一、主机发现 arp-scan -l靶机ip为192.168.55.163 二、端口扫描、目录枚举、漏洞扫描、指纹识别 2.1端口扫描 nmap --min-rate 10000 -p- 192.168.55.163发现并无特殊端口开放 扫描一下UDP端口 nmap -sU --min-rate 10000 -p- 192.168.55.163没有扫描到UDP端口 2.2目录枚…...
Cursor IDE 入门指南
什么是 Cursor? Cursor 是一款集成了 AI 功能的现代代码编辑器,基于 VSCode 开发,专为提高开发效率而设计。它内置强大的 AI 助手功能,能够理解代码、生成代码、解决问题,帮助开发者更快、更智能地完成编程任务。 基础功能 1.…...
来源于胡椒的亚甲二氧桥CYP450-文献精读119
Piper nigrum CYP719A37 Catalyzes the Decisive Methylenedioxy Bridge Formation in Piperine Biosynthesis 胡椒 (Piper nigrum) CYP719A37 催化胡椒碱生物合成中关键的亚甲二氧桥形成 摘要 胡椒 (Piper nigrum) 是世界上最受欢迎的香料之一。其主要辛辣成分胡椒碱 (piper…...
STM32八股【1】-----启动流程和startup文件理解
启动流程 知识点 MCU 上电复位。MSP从向量表第0个地址读取一个32位(2字节)的值并保存,该值为栈顶地址。PC计数器从第1个地址读取一个两字节的值并保存,该值为程序入口,一般是Reset_Handler。想了解FLASH地址映射可以…...
Docker与K8S是什么该怎么选?
用了很久的容器化,最近突然看到一个问题问: docker和K8S究竟有什么区别,到底该怎么选?我认真思考了一会,发现一时间还真说不明白,于是就研究了一段时间发布今天的博文! Docker vs Kubernetes&a…...
梦回杭州...
她对我说,烟雨中的西湖更别有情趣,我也怀着对‘人间天堂’的憧憬踏上了向往之旅。第一次亲密接触没有感觉中那么好,现在想起来是那时的人和心情都没能安静下来,去慢慢品味它的美。 六下杭州,亲历每一片风景,…...
NAT 实验:多私网环境下 NAPT、Easy IP 配置及 FTP 服务公网映射
NAT基本概念 定义:网络地址转换(Network Address Translation,NAT)是一种将私有(保留)地址转化为合法公网 IP 地址的转换技术,它被广泛应用于各种类型 Internet 接入方式和各种类型的网络中。作…...
SEED XSS 实验环境搭建步骤《精简版》
目录 1. 启动 SEED Ubuntu VM 2. 配置 /etc/hosts 3. 下载并解压 Labsetup.zip 4. 使用 Docker Compose 启动实验环境 5. 确保容器正常运行 6. 访问 Elgg Web 应用 7. 账户信息 8. 进入容器内部 9.实验环境搭建完成 🎉 10. 关闭实验 11.💡 重…...
YOLO数据集分割训练集、测试集和验证集
记录一下自己的分割代码。 注意: 这是在windows环境,请Linux的同学们注意。标签为txt,图像为jpg,其他的我没试过喔。 训练集、验证集、测试集(7:2:1) import os import shutil import random from tqdm…...
Debug-037-table列表勾选回显方案
效果展示: 图1 图2 最近实现一个支持勾选的el-table可以回显之前勾选项的功能。实现了一个“编辑”的功能: 在图1中的列表中有三行数据,当点击“更换设备”按钮时,打开抽屉显示el-table组件如图2所示,可以直接回显勾选…...
使用 libevent 构建高性能网络应用
使用 libevent 构建高性能网络应用 在现代网络编程中,高性能和可扩展性是开发者追求的核心目标。为了实现这一目标,许多开发者选择使用事件驱动库来管理 I/O 操作和事件处理。libevent 是一个轻量级、高性能的事件通知库,广泛应用于网络服务…...
人脸表情识别系统分享(基于深度学习+OpenCV+PyQt5)
最近终于把毕业大论文忙完了,众所周知硕士大论文需要有三个工作点,表情识别领域的第三个工作点一般是做一个表情识别系统出来,如下图所示。 这里分享一下这个表情识别系统: 采用 深度学习OpenCVPyQt5 构建,主要功能包…...
AtCoder - arc086_d Shift and Decrement分析与实现
分析与思路 可以把操作流程表示成下图 以进行四次除法操作为例: 这里有一个关键点:对于每个p_i (0< i <x-1) ,x是除法操作的次数,如果p_i>2,可以将2个p_i的减法操作去掉,在p_(i1)中增加一个减法…...
学习111
项目名称项目简介主要功能技术原理GitHub地址browser-use智能浏览器工具,让AI像人类一样操作浏览器,实现网页自动化网页浏览与操作、多标签页管理、视觉识别与内容提取、操作记录与重复执行、自定义动作支持、主流LLM模型支持为大语言模型服务的创新Pyth…...
Android Jetpack Compose介绍
Android Jetpack Compose Android Jetpack Compose 是 Google 推出的现代 UI 工具包,用于以声明式的方式构建 Android 应用的 UI。它摒弃了传统的 XML 布局方式,完全基于 Kotlin 编写,提供了更简洁、更强大的 UI 开发体验。以下是 Compose 的…...
tcping 命令的使用,ping IP 和端口
1. Windows系统安装 下载tcping工具:根据系统位数(32位或64位)下载对应的tcping.exe文件。安装步骤: 将下载的tcping.exe文件复制到C:\Windows\System32目录下。如果下载的是64位版本,需将文件名改为tcpi…...
天地图InfoWindow插入React自定义组件
截至2025年03月21日天地图的Marker不支持添加Label; 同时Label和Icon是不支持自定义HTMLElement只支持String;目前只有InfoWindow支持自定义HTMLElement; 效果图 React核心api import ReactDOM from react-dom/client const content document.createElement(div);…...
003-掌控命令行-CLI11-C++开源库108杰
首选的现代C风格命令行参数解析器! (本课程包含两段教学视频。) 以文件对象监控程序为实例,五分钟实现从命令行读入多个监控目标路径;区分两大时机,学习 CLI11 构建与解析参数两大场景下的异常处理;区分三…...
理解 Node.js 中的 process`对象与常用操作
理解 Node.js 中的 process 对象与常用操作 在 Node.js 中,process 是一个全局对象,提供了与当前 Node.js 进程相关的信息和操作。无论是获取进程信息、处理信号、访问环境变量,还是控制进程行为,process 都是不可或缺的工具。 看…...
鸿蒙HarmonyOS NEXT应用崩溃分析及修复
鸿蒙HarmonyOS NEXT应用崩溃分析及修复 如何保证应用的健壮性,其中一个指标就是看崩溃率,如何降低崩溃率,就需要知道存在哪些崩溃,然后对症下药,解决崩溃。那么鸿蒙应用中存在哪些崩溃类型呢?又改如何解决…...
【conda activate无效】 conda: error: argument COMMAND: invalid choice: ‘activate‘
conda activate失效了 在使用conda activate时出现报错: usage: conda [-h] [-v] [--no-plugins] [-V] COMMAND ... conda: error: argument COMMAND: invalid choice: activate (choose from clean, compare, config, create, info, init, install, list, notice…...
Redis + 布隆过滤器解决缓存穿透问题
Redis 布隆过滤器解决缓存穿透问题 1. Redis 布隆过滤器解决缓存穿透问题 📌 什么是缓存穿透? 缓存穿透指的是查询的数据既不在缓存,也不在数据库,导致每次查询都直接访问数据库,增加数据库压力。 例如࿱…...
机器学习——分类、回归、聚类、LASSO回归、Ridge回归(自用)
纠正自己的误区:机器学习是一个大范围,并不是一个小的方向,比如:线性回归预测、卷积神经网络和强化学都是机器学习算法在不同场景的应用。 机器学习最为关键的是要有数据,也就是数据集 名词解释:数据集中的…...
HarmonyOS鸿蒙开发 BuilderParam在父组件的Builder的点击事件报错:Error message:is not callable
HarmonyOS鸿蒙开发 BuilderParam在父组件的Builder的点击事件报错:Error message:is not callable 最近在鸿蒙开发过程中,UI做好了,根据列表item进行点击跳转,报错了 报错信息如下 Error message:is not callable Stacktrace:at…...
【canvas】一键自动布局:如何让流程图节点自动找到最佳位置
一键自动布局:如何让流程图节点自动找到最佳位置 引言 在流程图、拓扑图和系统架构图设计中,节点布局往往是最令人头疼的问题。如果手动调整每个节点位置,不仅耗时费力,还难以保证美观性和一致性。本文将深入解析如何实现自动布…...
[每周一更]-(第137期):Go + Gin 实战:Docker Compose + Apache 反向代理全流程
文章目录 **1. Go 代码示例(main.go)****2. Dockerfile 多段构建**3.构建 Docker 镜像**4. docker-compose.yml 直接拉取镜像****5. 运行容器****6. 测试 API**7、配置域名访问**DNS解析:将域名转换为IP地址****DNS寻址示例** 8.错误记录 访问…...
HTTPS 加密过程详解
HTTPS 详解及其加密过程流程框架 HTTPS(Hypertext Transfer Protocol Secure)是一种基于 HTTP 协议的安全通信协议,通过 SSL/TLS 协议对传输数据进行加密和身份验证,解决了 HTTP 明文传输的安全隐患。以下是其核心原理和加密流程的…...
