状态模式详解:管理对象状态的利器
在软件设计中,我们经常会遇到需要根据对象的不同状态来执行不同行为的情况。为了优雅地管理这些状态及其对应的行为,状态模式(State Pattern)应运而生。本文将深入探讨状态模式的使用条件、Java代码实现,并结合现实社会场景进行说明。同时,我们还将探讨该模式在开源项目中的应用、使用最多的行业,以及未来可能的变种。
一、什么是状态模式
状态模式是一种行为设计模式,它允许一个对象在其内部状态改变时改变其行为。对象看起来好像修改了它的类。在状态模式中,我们将对象的状态封装成独立的类,并将状态之间的转换逻辑也封装在状态类中,从而使得状态的管理更加清晰和灵活。
二、状态模式的使用条件
-
当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时,可以使用状态模式。
-
当一个操作中含有庞大的多分支结构,并且这些分支依赖于对象的状态时,状态模式可以简化这些复杂的条件判断。
-
当状态转换逻辑十分复杂,且状态转换过程中需要执行大量操作时,状态模式可以将这些逻辑分散到各个状态类中,提高代码的可读性和可维护性。
三、Java代码示例
下面通过一个简单的Java代码示例来说明状态模式的使用。假设我们有一个订单系统,订单有不同的状态(如待支付、已支付、已发货、已完成等),并且不同状态下订单的行为也不同。
// 抽象状态类
interface OrderState { void handle(OrderContext context);
} // 具体状态类:待支付状态
class PendingPaymentState implements OrderState { @Override public void handle(OrderContext context) { System.out.println("订单处于待支付状态,等待用户支付..."); // 状态转换逻辑:支付成功后切换到已支付状态 context.setState(new PaidState()); }
} // 具体状态类:已支付状态
class PaidState implements OrderState { @Override public void handle(OrderContext context) { System.out.println("订单已支付,准备发货..."); // 状态转换逻辑:发货后切换到已发货状态 context.setState(new ShippedState()); }
} // 具体状态类:已发货状态
class ShippedState implements OrderState { @Override public void handle(OrderContext context) { System.out.println("订单已发货,等待用户确认收货..."); // 状态转换逻辑:确认收货后切换到已完成状态 context.setState(new CompletedState()); }
} // 具体状态类:已完成状态
class CompletedState implements OrderState { @Override public void handle(OrderContext context) { System.out.println("订单已完成,交易结束。"); // 无需再切换状态 }
} // 环境类:订单上下文,维护订单的状态并处理请求
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 StatePatternDemo { public static void main(String[] args) { OrderContext context = new OrderContext(new PendingPaymentState()); context.request(); // 处理订单请求,根据当前状态执行相应操作并触发状态转换 context.request(); // 模拟用户连续操作,观察状态变化及行为执行 context.request(); }
}
在上面的代码中,我们定义了一个抽象状态接口OrderState和四个具体状态类(PendingPaymentState、PaidState、ShippedState、CompletedState),每个状态类都实现了handle方法来处理订单请求并触发状态转换。OrderContext类作为环境类,维护了订单的当前状态,并提供了request方法来处理请求。客户端代码通过创建订单上下文对象并调用其request方法来模拟用户的操作,并观察状态的变化及行为的执行。
四、现实社会场景
状态模式在现实社会中也有广泛的应用。以电梯为例,电梯有多种状态(如停止状态、上行状态、下行状态等),并且不同状态下电梯的行为也不同。停止状态下,电梯会等待用户按下楼层按钮;上行状态下,电梯会向上升高并响应同方向的楼层按钮;下行状态下,电梯会向下降低并响应同方向的楼层按钮。这些状态之间的转换逻辑也十分复杂,需要根据用户的操作和电梯的当前状态来确定下一步的行为。通过状态模式,我们可以将这些复杂的逻辑分散到各个状态类中,使得代码更加清晰和易于维护。
五、开源项目中的应用
在开源项目中,状态模式的应用也屡见不鲜。以Spring Framework为例,Spring中的BeanWrapper类就使用了状态模式来管理JavaBean的不同状态(如未初始化状态、已初始化状态等)。这些状态之间的转换逻辑被封装在BeanWrapper内部的状态类中,从而简化了对JavaBean状态的管理和操作。
六、使用最多的行业
状态模式在多个行业中都有广泛的应用,但在游戏开发和金融系统中尤为常见。在游戏开发中,游戏对象的状态经常需要随着游戏进程的推进而改变,如角色的生命值状态、怪物的攻击状态等。通过状态模式,游戏开发者可以更加灵活地管理这些状态及其对应的行为。在金融系统中,订单和交易的状态转换也是非常重要的业务逻辑之一。状态模式可以帮助金融系统更加清晰地处理这些复杂的状态转换逻辑,提高系统的可靠性和稳定性。
七、未来可能的变种
随着技术的不断发展和应用场景的拓展,状态模式未来可能会产生一些新的变种或演化。例如,在分布式系统中,我们可能需要考虑状态的一致性和同步问题。这时,可以将状态模式与分布式一致性协议相结合,形成一种新的分布式状态管理模式。此外,在人工智能领域,随着状态空间的不断增大和状态的复杂性增加,我们可能需要利用机器学习等技术来自动推断和管理状态转换逻辑,从而形成一种智能化的状态管理模式。
八、总结
状态模式是软件工程中一种非常重要的设计模式,它允许对象在内部状态改变时改变其行为,从而简化了复杂的条件判断和状态转换逻辑。通过学习和掌握状态模式,我们可以更加灵活地管理对象的状态和行为,提高代码的可读性和可维护性。同时,我们也应该关注状态模式在实际项目中的应用场景和未来可能的发展趋势,以便更好地应对软件设计中的挑战和问题。
相关文章:
状态模式详解:管理对象状态的利器
在软件设计中,我们经常会遇到需要根据对象的不同状态来执行不同行为的情况。为了优雅地管理这些状态及其对应的行为,状态模式(State Pattern)应运而生。本文将深入探讨状态模式的使用条件、Java代码实现,并结合现实社会…...
探索----------------阿里云
目录 一、阿里云四大件 1、云服务器ECS 2、云数据库RDS 3、负载均衡SLB 4、对象存储OSS 5、其他的云计算产品 1)内容分发网络CDN 2)专有网络 VPC 二、linux发行版本 三、你平时对系统会怎么优化(五大负载) 1、cpu 使用率…...
Tidb和MySQL性能简单测试对比
一、单SQL性能对比 由于TiDB的并发能力优秀,但是单个SQL执行延迟较差,为了客观对比,所以只用1个线程来压测tidb和mysql,以观察延迟情况 二、并发SQL性能对比 TiDB:v6.5.2 MySQL:8.0.26 (单机) 三、结论 …...
2024.2.6力扣每日一题——魔塔游戏
2024.2.6 题目来源我的题解方法一 贪心优先队列 题目来源 力扣每日一题;题序:LCP 30 我的题解 方法一 贪心优先队列 思路:使用贪心的思想,从左到右遍历,若遇到加上当前房间的生命值后小于等于0,由于需要…...
C# OAuth单点登录的实现
原理 单点登录(Single Sign-On,简称SSO)是一种身份验证技术,它允许用户使用一组凭据(如用户名和密码)登录多个相关但独立的系统,而无需在每个系统中都进行登录操作。下面是一个简单的SSO实现示…...
AtCoder Beginner Contest 347 (ABCDEF题)视频讲解
A - Divisible Problem Statement You are given positive integers N N N and K K K, and a sequence of length N N N, A ( A 1 , A 2 , … , A N ) A(A_1,A_2,\ldots,A_N) A(A1,A2,…,AN). Extract all elements of A A A that are multiples of K K K, divi…...
【vue2+antvx6】报错Cannot read properties of undefined (reading ‘toUpperCase‘)
我的代码是这样的 <el-collapseref"collapse"v-model"active"accordionclass"collapseStart"change"collapsechange"><el-collapse-item:name"String(index 1)"v-for"(i, index) in List":key"in…...
主流的开发语言、环境及其特点
主流的开发语言及其特点: 1. Python:以其简洁的语法和强大的库支持而闻名,适用于数据科学、人工智能和网络开发等领域。 2. Java:跨平台的编程语言,广泛应用于企业级应用、Android 开发和大型系统开发。 3. C…...
Android知识 - 代码混淆ProGuard规则介绍
ProGuard 的规则及示例 规则概述 ProGuard 是一个代码优化工具,它通过移除未使用的代码、重命名类、字段和方法等方式来减小应用的大小。在 ProGuard 的配置文件中,我们可以定义一系列的规则来控制优化和混淆的过程。 规则语法 ProGuard 的规则通常包…...
【Linux的进程篇章 - 冯诺依曼的体系结构】
Linux学习笔记---005 Linux冯诺依曼体系结构理解1、冯诺依曼体系结构1.1、冯诺依曼体系结构1.2、硬件层面1.3、数据层面1.4、那么冯诺依曼体系能干什么呢? 2、操作系统(Operastor System)2.1、概念2.2、操作系统层的核心功能 3、进程的初步理解 Linux冯诺依曼体系结…...
flask-(数据连接池的使用,定制命令,信号的使用,表关系的建立和查询)
文章目录 连接池实例flask定制命令flask 缓存的使用flask信号的使用sqlalchemy原生操作sqlalchemy操作表flask orm操作表一对多的增加和跨表查询 (一对一只需要关联字段加上 ,uniqueTrue)多对多关系的增加和查询多对多基本的增删改查 连接池 import pymy…...
设计模式学习笔记 - 设计模式与范式 -行为型:2.观察者模式(下):实现一个异步非阻塞的EventBus框架
概述 《1.观察者模式(上)》我们学习了观察者模式的原理、实现、应用场景,重点节介绍了不同应用场景下,几种不同的实现方式,包括:同步阻塞、异步非阻塞、进程内、进程间的实现方式。 同步阻塞最经典的实现…...
数据挖掘|贝叶斯分类器及其Python实现
分类分析|贝叶斯分类器及其Python实现 0. 分类分析概述1. Logistics回归模型2. 贝叶斯分类器2.1 贝叶斯定理2.2 朴素贝叶斯分类器2.2.1 高斯朴素贝叶斯分类器2.2.2 多项式朴素贝叶斯分类器 2.3 朴素贝叶斯分类的主要优点2.4 朴素贝叶斯分类的主要缺点 3. 贝叶斯分类器在生产中的…...
Linux文件(系统)IO(含动静态库的链接操作)
文章目录 Linux文件(系统)IO(含动静态库的链接操作)1、C语言文件IO操作2、三个数据流stdin、stdout、stderr3、系统文件IO3.1、相关系统调用接口的使用3.2、文件描述符fd3.3、文件描述符的分配规则3.3、重定向3.4、自制shell加入重…...
CI/CD实战-jenkins结合ansible 7
配置主机环境 在jenkins上断开并删除docker1节点 重新给master添加构建任务 将server3,server4作为测试主机,停掉其上后面的docker 在server2(jenkins)主机上安装ansible 设置jenkins用户到目标主机的免密 给测试主机创建用户并…...
内网渗透-(黄金票据和白银票据)详解(一)
目录 一、Kerberos协议 二、下面我们来具体分析Kerberos认证流程的每个步骤: 1、KRB_AS-REQ请求包分析 PA-ENC-TIMESTAMP PA_PAC_REQUEST 2、 KRB_AS_REP回复包分析: TGT认购权证 Logon Session Key ticket 3、然后继续来讲相关的TGS的认证过程…...
学习transformer模型-Dropout的简明介绍
Dropout的定义和目的: Dropout 是一种神经网络正则化技术,它在训练时以指定的概率丢弃一个单元(以及连接)p。 这个想法是为了防止神经网络变得过于依赖特定连接的共同适应,因为这可能是过度拟合的症状。直观上&#…...
游戏引擎中的大气和云的渲染
一、大气 首先和光线追踪类似,大气渲染也有类似的渲染公式,在实际处理中也有类似 Blinn-Phong的拟合模型。关键参数是当前点到天顶的角度和到太阳的角度 二、大气散射理论 光和介质的接触: Absorption 吸收Out-scattering 散射Emission …...
华为鲲鹏云认证考试内容有哪些?华为鲲鹏云认证考试报名条件
华为鲲鹏云认证考试是华为公司为了验证IT专业人士在鲲鹏计算及云计算领域的专业能力而设立的一项认证考试。以下是关于华为鲲鹏云认证考试的一些详细信息: 考试内容:华为鲲鹏云认证考试的内容主要包括理论考核和实践考核两大部分。理论考核涉及云计算、…...
v3-admin-vite 改造自动路由,view页面自解释Meta
需求 v3-admin-vite是一款不错的后端管理模板,主要是pany一直都在维护,最近将后台管理也进行了升级,顺便完成一直没时间解决的小痛痒: 在不使用后端动态管理的情况下。我不希望单独维护一份路由定义,我希望页面是自解…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
JDK 17 序列化是怎么回事
如何序列化?其实很简单,就是根据每个类型,用工厂类调用。逐个完成。 没什么漂亮的代码,只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...
FTXUI::Dom 模块
DOM 模块定义了分层的 FTXUI::Element 树,可用于构建复杂的终端界面,支持响应终端尺寸变化。 namespace ftxui {...// 定义文档 定义布局盒子 Element document vbox({// 设置文本 设置加粗 设置文本颜色text("The window") | bold | color(…...
Docker、Wsl 打包迁移环境
电脑需要开启wsl2 可以使用wsl -v 查看当前的版本 wsl -v WSL 版本: 2.2.4.0 内核版本: 5.15.153.1-2 WSLg 版本: 1.0.61 MSRDC 版本: 1.2.5326 Direct3D 版本: 1.611.1-81528511 DXCore 版本: 10.0.2609…...
【题解-洛谷】P10480 可达性统计
题目:P10480 可达性统计 题目描述 给定一张 N N N 个点 M M M 条边的有向无环图,分别统计从每个点出发能够到达的点的数量。 输入格式 第一行两个整数 N , M N,M N,M,接下来 M M M 行每行两个整数 x , y x,y x,y,表示从 …...
Vue 实例的数据对象详解
Vue 实例的数据对象详解 在 Vue 中,数据对象是响应式系统的核心,也是组件状态的载体。理解数据对象的原理和使用方式是成为 Vue 专家的关键一步。我将从多个维度深入剖析 Vue 实例的数据对象。 一、数据对象的定义方式 1. Options API 中的定义 在 Options API 中,使用 …...
