状态机模式
状态模式
- 状态模式定义:
- 使用场景
- 角色定义
- 1. State一抽象状态角色
- 2. ConcreteState一-具体状态角色
- 3. Context--环境角色
- 需求背景
- 1. 订单状态抽象类
- 2. 定义订单具体状态类并集成基类(抽象类)
- 2.1 订单创建状态
- 2.2 订单已支付状态
- 2.3 订单已发货状态
- 2.4 订单已签收状态
- 2.5 订单已确认收货状态
- 2.6 订单已取消状态
- 3. 订单上下文类
- 4. 测试案例
- 5. 案例说明
- 5.1 在测试案例中,我们首先创建了一个OrderContext对象,并在其上调用pay()方法,此时订单状态从CreatedState转换为PaidState。
- 5.2 接着依次调用了ship()、deliver()和receive()方法,订单状态分别从PaidState转换为ShippedState、ShippedState转换为DeliveredState、DeliveredState转换为ReceivedState。
- 5.3 然后尝试再次调用receive()、ship()、pay()和deliver()方法,此时订单状态已经处于ReceivedState,不能再进行状态转换了。
- 5.4 最后调用了cancel()方法,此时订单状态由ReceivedState转换为CancelledState。
状态模式定义:
当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类
使用场景
使用场景: 1、行为随状态改变而改变的场景。 2、条件、分支语句的代替者。
角色定义
1. State一抽象状态角色
接口或抽象类,负责对象状态定义,并且封装环境角色以实现状态切换
2. ConcreteState一-具体状态角色
每一个具体状态必须完成两个职责: 本状态的行为管理以及趋向状态处理,通俗地说,就是本状态下要做的事情,以及本状态如何过渡到其他状态。
3. Context–环境角色
定义客户端需要的接口,并且负责具体状态的切换
需求背景
针对用户购买的商品完成订单不同状态之间的流(未支付、已支付、已发货、已签收、已确认等)。
下面是一个简单的Java示例代码:
1. 订单状态抽象类
// 订单状态抽象类
abstract class OrderState {protected OrderContext context;public void setContext(OrderContext context) {this.context = context;}public abstract void pay();public abstract void cancel();public abstract void ship();public abstract void deliver();public abstract void receive();
}
2. 定义订单具体状态类并集成基类(抽象类)
2.1 订单创建状态
// 订单创建状态
class CreatedState extends OrderState {@Overridepublic void pay() {System.out.println("订单已支付");context.setState(new PaidState());}@Overridepublic void cancel() {System.out.println("订单已取消");context.setState(new CancelledState());}@Overridepublic void ship() {System.out.println("订单尚未支付,不能发货");}@Overridepublic void deliver() {System.out.println("订单尚未支付,不能发货");}@Overridepublic void receive() {System.out.println("订单尚未支付,不能确认收货");}
}
2.2 订单已支付状态
// 订单已支付状态
class PaidState extends OrderState {@Overridepublic void pay() {System.out.println("订单已支付,无需再次支付");}@Overridepublic void cancel() {System.out.println("订单已取消");context.setState(new CancelledState());}@Overridepublic void ship() {System.out.println("订单已发货");context.setState(new ShippedState());}@Overridepublic void deliver() {System.out.println("订单尚未发货,不能确认收货");}@Overridepublic void receive() {System.out.println("订单尚未发货,不能确认收货");}
}
2.3 订单已发货状态
// 订单已发货状态
class ShippedState extends OrderState {@Overridepublic void pay() {System.out.println("订单已支付,无需再次支付");}@Overridepublic void cancel() {System.out.println("订单已发货,不能取消");}@Overridepublic void ship() {System.out.println("订单已发货,无需再次发货");}@Overridepublic void deliver() {System.out.println("订单已签收");context.setState(new DeliveredState());}@Overridepublic void receive() {System.out.println("订单尚未签收,不能确认收货");}
}
2.4 订单已签收状态
// 订单已签收状态
class DeliveredState extends OrderState {@Overridepublic void pay() {System.out.println("订单已支付,无需再次支付");}@Overridepublic void cancel() {System.out.println("订单已签收,不能取消");}@Overridepublic void ship() {System.out.println("订单已签收,不能再次发货");}@Overridepublic void deliver() {System.out.println("订单已签收,不能再次确认收货");}@Overridepublic void receive() {System.out.println("订单已确认收货");context.setState(new ReceivedState());}
}
2.5 订单已确认收货状态
// 订单已确认收货状态
class ReceivedState extends OrderState {@Overridepublic void pay() {System.out.println("订单已支付,无需再次支付");}@Overridepublic void cancel() {System.out.println("订单已确认收货,不能取消");}@Overridepublic void ship() {System.out.println("订单已确认收货,不能再次发货");}@Overridepublic void deliver() {System.out.println("订单已确认收货,不能再次确认收货");}@Overridepublic void receive() {System.out.println("订单已确认收货,无需再次确认");}
}
2.6 订单已取消状态
//订单已取消
public class CancelledState extends OrderState {@Overridepublic void pay() {System.out.println("订单已取消");}@Overridepublic void cancel() {System.out.println("订单已取消");}@Overridepublic void ship() {System.out.println("订单已取消");}@Overridepublic void deliver() {System.out.println("订单已取消");}@Overridepublic void receive() {System.out.println("订单已取消");}
}
3. 订单上下文类
// 订单上下文类
class OrderContext {private OrderState state;public OrderContext() {setState(new CreatedState());}public void setState(OrderState state) {this.state = state;this.state.setContext(this);}public void pay() {state.pay();}public void cancel() {state.cancel();}public void ship() {state.ship();}public void deliver() {state.deliver();}public void receive() {state.receive();}
}
4. 测试案例
// 测试案例
public class StateTest {public static void main(String[] args) {OrderContext order = new OrderContext();order.pay(); // 订单已支付order.ship(); // 订单已发货order.deliver(); // 订单已签收order.receive(); // 订单已确认收货order.receive(); // 订单已确认收货,无需再次确认order.ship(); // 订单已确认收货,不能再次发货order.pay(); // 订单已确认收货,无需再次支付order.deliver(); // 订单已确认收货,不能再次确认收货order.cancel(); // 订单已确认收货,不能取消}
}
5. 案例说明
5.1 在测试案例中,我们首先创建了一个OrderContext对象,并在其上调用pay()方法,此时订单状态从CreatedState转换为PaidState。
5.2 接着依次调用了ship()、deliver()和receive()方法,订单状态分别从PaidState转换为ShippedState、ShippedState转换为DeliveredState、DeliveredState转换为ReceivedState。
5.3 然后尝试再次调用receive()、ship()、pay()和deliver()方法,此时订单状态已经处于ReceivedState,不能再进行状态转换了。
5.4 最后调用了cancel()方法,此时订单状态由ReceivedState转换为CancelledState。
相关文章:
状态机模式
状态模式 状态模式定义:使用场景角色定义1. State一抽象状态角色2. ConcreteState一-具体状态角色3. Context--环境角色 需求背景1. 订单状态抽象类2. 定义订单具体状态类并集成基类(抽象类)2.1 订单创建状态2.2 订单已支付状态2.3 订单已发货状态2.4 订…...
瑞吉外卖:后台系统登录功能
文章目录 需求分析代码开发创建实体类导入返回结果类Rcontroller、service与mapperlogin.html 需求分析 点击登录按钮后,浏览器以POST方式向employee/login提交username和password,服务器经过处理后向浏览器返回某种格式的数据,其中包含&…...
Linux拓展:链接库
一.说明 本篇博客介绍Linux操作系统下的链接库相关知识,由于相关概念已在Windows下链接库一文中介绍,本篇博客直接上操作。 二.静态链接库的创建和使用 1.提前看 这里主要介绍的是C语言的链接库技术,而在Linux下实现C语言程序,…...
基于.Net开发的、支持多平台、多语言餐厅点餐系统
今天给大家推荐一套支持多平台、多语言版本的订单系统,适合餐厅、酒店等场景。 项目简介 这是基于.Net Framework开发的,支持手机、平板、PC等平台、多语言版本开源的点餐系统,非常适合餐厅、便利店、超市、酒店等,该系统基础功…...
Windows系统SSL/TLS安全协议介绍
支持安全加密的https底层使用的就是SSL/TLS,在发起https请求之前需要先建立TCP连接,之后再进行SSL/TLS协议协商,协商通过后才能发起https请求。本文将详细介绍SSL/TLS协议相关的内容。 之前在项目中就出现过客户端SSL/TLS版本过低,导致向服务器发起连接时被服务器拒绝的问题…...
ovs-vsctl 命令详解
ovs-vsctl 命令详解 网桥Bridge 创建 Bridge ovs-vsctl add-br br0 删除 Bridge ovs-vsctl del-br br0 列出 Bridge ovs-vsctl list-br 显示详情 ovs-vsctl show 端口 Port 添加端口 ovs-vsctl add-port br0 p1 其中br0 为上面添加的bridge p1可以是物理端口或者vN…...
具备“记忆”功能的VBA目录选择器
大家使用任意一款浏览器(例如:Chrome、Edge)下载文件时,如果【另存为】对话框选择C:\Download,那么下次再次使用【另存为】功能,对话框默认显示C:\Download,而不是根目录。 在VBA开发中调用目录…...
electron入门 | 手把手带electron项目初始化
Electron是一个基于Chromium和 Node.js,可以使用 HTML、CSS和JavaScript构建跨平台应用的技术框架,兼容 Mac、Windows 和 Linux。 目录 1.了解electron 2.开发环境 3.初始化 采坑插曲: 1.了解electron Electron 可以让你使用纯 JavaScrip…...
力扣解法汇总2423. 删除字符使频率相同
目录链接: 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目: https://github.com/September26/java-algorithms 原题链接:力扣 描述: 给你一个下标从 0 开始的字符串 word ,字符串只包含小写英文字母。你…...
【超算/先进计算学习】日报8
目录 今日已完成任务列表遇到的问题及解决方案任务完成详细笔记阶段一阶段二阶段三阶段四 对自己的表现是否满意简述下次计划其他反馈 今日已完成任务列表 超算/高性能计算总结 遇到的问题及解决方案 无 任务完成详细笔记 阶段一 在学习的第一阶段,我们首先对需要…...
《LearnUE——基础指南:上篇—2》——GamePlay架构之Level和World
目录 听说世界是由多个Level组成的 1.2.1 引言 1.2.2 建造大陆(ULevel) 1.2.3构建世界(World) 1.2.4总结 听说世界是由多个Level组成的 1.2.1 引言 上小节谈到Actor和Component的关系,UE利用Actor的概念组成了世…...
IDEA部署tomcat项目
文章目录 只是部署一下看到这里即可war和war exploded的区别warwar exploded update的动作update resourcesupdate classes and resourcesredeployrestart server 解决了拿到了一个tomcat项目后如何将它部署到IDEA里面的问题。 file->open 选中pom.xml并open as project …...
IAM角色
Identity-based policy,它关联到特定的User/Role/Group上,指定这些主体能对哪些资源进行怎样的操作 Resource-based policy,它关联到具体的AWS资源上,指定哪些主体可以对这个资源做怎样的操作 aws受信任关系视为aws服务可以实现&a…...
【VAR | 时间序列】以美国 GDP 和通货膨胀数据为例的VAR模型简单实战(含Python源代码)
以美国 GDP 和通货膨胀数据为例: 1. 数据集 下载数据我们需要从 FRED 数据库下载美国 GDP 和通货膨胀数据,并将它们存储在 CSV 文件中。可以在 FRED 网站(https://fred.stlouisfed.org/)搜索并下载需要的数据。在这里࿰…...
常用的设计模式之二(行为型模式)
文章目录 观察者模式模板模式 观察者模式 观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有观察者都会收到通知并进行相应的处理。 观察者…...
MYSQL基本操作(增删改查)
数据库的列类型 int:整型 用于定义整数类型的数据 float:单精度浮点4字节32位 准确表示到小数点后六位 double:双精度浮点8字节64位 char:固定长度的字符类 用于定义字符类型数据&…...
双周赛103(模拟、网格图BFS、树状数组)
文章目录 双周赛103[6406. K 个元素的最大和](https://leetcode.cn/problems/maximum-sum-with-exactly-k-elements/)模拟 [6405. 找到两个数组的前缀公共数组](https://leetcode.cn/problems/find-the-prefix-common-array-of-two-arrays/)模拟 [6403. 网格图中鱼的最大数目](…...
【数据结构】二叉树(详细)
二叉树 1.树1.1定义1.2基本术语1.3树形结构和线性结构1.4树的存储结构1.4.1双亲表示法1.4.2孩子兄弟表示法 2.二叉树2.1定义2.2特殊二叉树2.3性质2.4存储结构2.4.1顺序存储2.4.2链式存储结构 3.二叉树的基本操作3.1前序遍历(先序遍历)3.2中序遍历3.3后序…...
蓝牙耳机哪款性价比高一些?2023年性价比最高的蓝牙耳机推荐
随着科技的进步,蓝牙耳机已然成为我们生活中的一部分,无论是通勤、追剧、运动或者玩游戏,大都会用到蓝牙耳机。那么,哪款蓝牙耳机的性价比高一些?相信大多数人在选择产品的时候,都会看性价比。接下来&#…...
等保2.0存在的问题
等保制度和技术要求 国家信息安全等级保护制度(二级)相关要求包含技术要求和管理要求,技术要求包含:物理安全、网络安全、主机安全、应用安全及数据安全及备份恢复;管理要求包含:安全管理机构、安全管理制度、人员安全管理、系统建设管理、系统运维管理。 一、 技术要求 …...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...
Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...
