Java 实现简单状态机(订单状态流转)

一、状态变化

拿支付来说,正常流程如下

  • 订单创建 ---> 订单确认
  • 订单确认 ---> 已支付
  • 已支付 ---> 交易成功

不合法的流程

  • 订单创建 ---> 交易成功

而状态的变化,通常是靠事件来驱动的,因此我们可以设计一个状态机,存储哪些状态 + 什么样的事件 => 新的状态

代码实现时,我们 可以把 原状态+事件 作为key,新的状态作为 value

项目启动时,通过 静态代码块 初始化那些合法的状态变化到 hashmap 中,使用时,通过查询 map 是否存在这样的key所对应的 value,存在则表示允许状态转移,否则抛异常。

所谓的事件,通常都是一个枚举类,用来表示事件类型。

二、代码实现如下

定义一个接口

java 复制代码
public interface StateMachine<STATE, EVENT> {

    /**
     * 状态机转移
     *
     * @param state
     * @param event
     * @return
     */
    STATE transition(STATE state, EVENT event);
}

在定义一个基类,实现该接口

java 复制代码
public class BaseStateMachine<STATE, EVENT> implements StateMachine<STATE, EVENT> {
    private Map<String, STATE> stateTransitions = new HashMap<>();

    protected void putTransition(STATE origin, EVENT event, STATE target) {
        stateTransitions.put(Joiner.on("_").join(origin, event), target);
    }

    @Override
    public STATE transition(STATE state, EVENT event) {
        STATE target = stateTransitions.get(Joiner.on("_").join(state, event));
        if (target == null) {
            throw new BizException("state = " + state + " , event = " + event, STATE_MACHINE_TRANSITION_FAILED);
        }
        return target;
    }
}

具体的业务需要时,继承该类,往map添加具体的状态即可 例如:支付的如下

java 复制代码
public class OrderStateMachine extends BaseStateMachine<TradeOrderState, TradeOrderEvent> {

    public static final OrderStateMachine INSTANCE = new OrderStateMachine();

    {
        putTransition(TradeOrderState.CREATE, TradeOrderEvent.CONFIRM, TradeOrderState.CONFIRM);
        putTransition(TradeOrderState.CONFIRM, TradeOrderEvent.PAY, TradeOrderState.PAID);
        putTransition(TradeOrderState.PAID, TradeOrderEvent.FINISH, TradeOrderState.FINISH);
    }

}
相关推荐
apcipot_rain几秒前
C++转Java日记(03)
java·开发语言·c++
皮皮林551几秒前
Java实现微信扫码登录
java
陈随易2 小时前
纯 Go 写的 JS 引擎,跑分超过了 C 语言的 QuickJS
前端·后端·程序员
Yyyyyy~2 小时前
【Java】Day4Web基础知识
java·spring boot
卷无止境3 小时前
RAGFlow 项目全景报告:从文档解析引擎到 Agent 原生数据库
后端·python
小Z先生3 小时前
我用 Go + 系统 WebView 写了个纯本地 Postman:不装 Electron、不连云端
后端·github
IT_陈寒4 小时前
Redis连接池泄漏那次,我差点把生产环境搞崩了
前端·人工智能·后端
灿飞屋4 小时前
Kotlin与Java虚拟机三:控制流
android·java·开发语言·后端·python·kotlin·安卓
石小石Orz4 小时前
AI 正在蚕食我们的编码能力
前端·后端·算法
NE_STOP4 小时前
Spring AI Alibaba - MCP入门
java