状态机模式
状态模式
- 状态模式定义:
- 使用场景
- 角色定义
- 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存在的问题
等保制度和技术要求 国家信息安全等级保护制度(二级)相关要求包含技术要求和管理要求,技术要求包含:物理安全、网络安全、主机安全、应用安全及数据安全及备份恢复;管理要求包含:安全管理机构、安全管理制度、人员安全管理、系统建设管理、系统运维管理。 一、 技术要求 …...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...
简单介绍C++中 string与wstring
在C中,string和wstring是两种用于处理不同字符编码的字符串类型,分别基于char和wchar_t字符类型。以下是它们的详细说明和对比: 1. 基础定义 string 类型:std::string 字符类型:char(通常为8位)…...
Netty自定义协议解析
目录 自定义协议设计 实现消息解码器 实现消息编码器 自定义消息对象 配置ChannelPipeline Netty提供了强大的编解码器抽象基类,这些基类能够帮助开发者快速实现自定义协议的解析。 自定义协议设计 在实现自定义协议解析之前,需要明确协议的具体格式。例如,一个简单的…...
【Redis】Redis从入门到实战:全面指南
Redis从入门到实战:全面指南 一、Redis简介 Redis(Remote Dictionary Server)是一个开源的、基于内存的键值存储系统,它可以用作数据库、缓存和消息代理。由Salvatore Sanfilippo于2009年开发,因其高性能、丰富的数据结构和广泛的语言支持而广受欢迎。 Redis核心特点:…...