当前位置: 首页 > news >正文

状态机模式

状态模式

  • 状态模式定义:
    • 使用场景
    • 角色定义
        • 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语言程序&#xff0c…...

基于.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/)搜索并下载需要的数据。在这里&#xff0…...

常用的设计模式之二(行为型模式)

文章目录 观察者模式模板模式 观察者模式 观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有观察者都会收到通知并进行相应的处理。 观察者…...

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存在的问题

等保制度和技术要求 国家信息安全等级保护制度(二级)相关要求包含技术要求和管理要求,技术要求包含:物理安全、网络安全、主机安全、应用安全及数据安全及备份恢复;管理要求包含:安全管理机构、安全管理制度、人员安全管理、系统建设管理、系统运维管理。 一、 技术要求 …...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...