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

Java状态机

目录

1. 概念

2. 定义状态机

3. 生成一个状态机

4. 使用


1. 概念

        在Java的应用开发里面,应该会有不少的人接触到一个业务场景下,一个数据的状态会发生多种变化,最经典的例子例如订单,当然还有像用户的状态变化(冻结,销户等),文章的状态变化(已发布,草稿等)。像这些具有多种状态的事物,如果我们不进行一些措施来进行维护和扩展的话,那么将会导致状态越难越难以管理,而且对状态的转变也会越来越难以定义。

        那么讲出了它现在存在的问题,也就能大概知道本文要讲的是主要内容是什么了。没错,状态机就是用来规范使用状态的各种变化的一种产物。

        可能大家还不清楚这个玩意为什么产生,我给大家一个场景,如果没有一种严格的状态机控制,那么像订单这种,我们是不是可以直接从已下单的状态直接推进到已发货的状态,而越过中间的支付等等的中间状态。这显然是有问题的。

        在状态机当中,具有四个概念,用来控制状态的变化。一种状态需要迁移到下一种状态,一定是经过某种行为或者事件转化到下一个状态。所以这也就成为了状态机的核心概念。​​​​​​

  1. 状态(States):代表系统可能处于的各种状态,例如 "已下单"、"已支付"、"已发货" 等。

  2. 事件(Events):触发状态转换的事件,例如 "下单"、"支付"、"发货" 等。

  3. 动作(Actions):在状态转换发生时执行的操作或行为。

  4. 转换(Transitions):定义状态之间的转换规则,即在某个事件发生时,系统从一个状态转换到另一个状态的规则

2. 定义状态机

我们可以定义一个状态机,并声明两个变量,一个用来记录状态变化的记录,一个用来记录要经过下一个状态需要的源状态与事件。在生成一个状态机的过程,我们将记录他需要变化的所有的状态,事件以及转换。

public class StateMachine {private Map<String,String> translatedTransitionsMap = new HashMap<>();private Set<String> translatedTransitions = new HashSet<>();private static final String DEFAULT_DELIMITER = "->";public StateMachine(Transition[] transitions){for (Transition transition : transitions) {translatedTransitions.add(transition.getFrom() + DEFAULT_DELIMITER +transition.getEvent() + DEFAULT_DELIMITER+ transition.getTo());if(translatedTransitionsMap.containsKey(transition.getFrom() + DEFAULT_DELIMITER + transition.getEvent())){throw new RuntimeException("Duplicate transition found: " +transition.getFrom() +DEFAULT_DELIMITER +transition.getAction());}translatedTransitionsMap.put(transition.getFrom() + DEFAULT_DELIMITER + transition.getEvent(),transition.getTo());}}public String getNextState(String from, String event){return translatedTransitionsMap.get(from + DEFAULT_DELIMITER + event);}public boolean checkTransitions(String from, String even){return translatedTransitions.contains(from + DEFAULT_DELIMITER + event);}}

过渡类的内容为

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Transition {/*** 起始状态*/private String from;/*** 动作*/private String even;/*** 目标状态*/private String to;}

3. 生成一个状态机

我们此次以订单举例,生成一个订单的状态机

public class OrderStatusModel {private static StateMachine ORDEER_STATEMACHINE;static {ORDEER_STATEMACHINE = new StateMachine(new Transition[]{new Transition(TradeStatusEnum.NEW.getStatus(), TradeEventEnum.CONFIRM.name(), TradeStatusEnum.WAIT_PAY.getStatus()),new Transition(TradeStatusEnum.NEW.getStatus(), TradeEventEnum.CANCEL.name(), TradeStatusEnum.CLOSED.getStatus()),new Transition(TradeStatusEnum.WAIT_PAY.getStatus(), TradeEventEnum.PAY.name(), TradeStatusEnum.PAY_SUCCESS.getStatus()),new Transition(TradeStatusEnum.WAIT_PAY.getStatus(), TradeEventEnum.PAY_CANCEL.name(), TradeStatusEnum.CANCELLED.getStatus()),new Transition(TradeStatusEnum.PAY_SUCCESS.getStatus(), TradeEventEnum.CONFIRM_SUCCESS.name(), TradeStatusEnum.COMPLETED.getStatus())});}public static String getTargetStatus(TradeStatusEnum currentStatus, TradeEventEnum tradeEventEnum) {return ORDEER_STATEMACHINE.getNextState(currentStatus.getStatus(), tradeEventEnum.name());}}

订单状态枚举

@Getter
public enum TradeStatusEnum {/*** 新建订单*/NEW("NEW", "新建订单"),/*** 锁单成功-待支付状态*/WAIT_PAY("WAIT_PAY", "待支付"),/*** 支付成功*/PAY_SUCCESS("PAY_SUCCESS", "支付成功"),/*** 已完成*/COMPLETED("COMPLETED","已完成"),/*** 已取消*/CANCELLED("CANCELLED","已取消"),/*** 订单关闭*/CLOSED("CLOSED","订单关闭");private String status;private String desc;TradeStatusEnum(String status, String desc) {this.status = status;this.desc = desc;}
}

订单事件

public enum TradeEventEnum {/*** 订单确认*/CONFIRM,/*** 取消订单*/CANCEL,/*** 支付*/PAY,/*** 支付取消*/PAY_CANCEL,/*** 订单确认成功*/CONFIRM_SUCCESS,/*** 订单完成*/FINISH
}

4. 使用

@Data
public class TradeOrder {private String orderId;private String status;private double price;public TradeOrder confirm(TradeCreateRequest request) {this.setStatus(OrderStatusModel.getTargetStatus(request.getTradeStatus(), TradeEventEnum.CONFIRM));return this;}public TradeOrder pay(TradeWaitPayRequest request) {this.setStatus(OrderStatusModel.getTargetStatus(request.getTradeStatus(), TradeEventEnum.CANCEL));return this;}
}

传参为

public class TradeCreateRequest extends BaseResquest{@Overridepublic TradeStatusEnum getTradeStatus(){return TradeStatusEnum.NEW;}
}
public abstract class BaseResquest {abstract TradeStatusEnum getTradeStatus();
}

http://www.lryc.cn/news/539010.html

相关文章:

  • 【Pandas】pandas Series isin
  • 通过VSCode直接连接使用 GPT的编程助手
  • 一种最常见的js加密解密
  • 【Python爬虫(4)】揭开Python爬虫的神秘面纱:基础概念全解析
  • SMOJ 一笔画/洛谷 P7171 COCI 2020/2021 #3 Selotejp 题解
  • 【Java学习】继承
  • 计时器任务实现(保存视频和图像)
  • 树莓百度百科能否揭开成都树莓集团的神秘面纱?
  • 【如何看懂数据手册和原理图】
  • SQL 优化工具使用之 explain 详解
  • 深度解析Unity3D渲染管线:网格、材质与GPU渲染的协同逻辑
  • POI优化Excel录入
  • 实时图像与视频超分辨率:高效子像素卷积网络(ESPCN)解析
  • QT--对话框的切换
  • 深入浅出:CUDA是什么,如何利用它进行高效并行计算
  • Zotero PDF Translate插件配置百度翻译api
  • 利用acme.sh 申请 Google 免费证书
  • 腾讯云cloudstudio使用笔记(一)
  • python自动化制作常规的日报数据可视化
  • C语言:在主函数中输入十个等长的字符串。用另一函数对它们排序,然后在主函数输出这10个已排好序的字符串。
  • 构建高效智能对话前端:基于Ant Design X 的deepseek对话应用
  • SQLMesh 系列教程5- 详解SQL模型
  • 本地DeepSeek模型GGUF文件转换为PyTorch格式
  • Flutter:动态表单(在不确定字段的情况下,生成动态表单)
  • 【Python项目】文本相似度计算系统
  • C# ref 和 out 的使用详解
  • Ubuntu 24.04.1 LTS 本地部署 DeepSeek 私有化知识库
  • 用 WOW.js 和 animate.css 实现动画效果
  • 1-知识图谱-概述和介绍
  • flink jobgraph详细介绍