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);
    }

}
相关推荐
zz在掘金337081 小时前
MongoDB 脚本速查
后端
随性而行3601 小时前
企业微信 API 如何实现业务消息自动通知?接口应用场景解析
java·人工智能·后端·微信·机器人·企业微信
Mav1 小时前
[个人学习记录]从零构建高性能 LLM 推理网关:长连接优雅停机(Graceful Drain)、K8s 探针联动与 Context 底层哲学
后端
团子哒哒1 小时前
变量、常量和数据类型
后端
zz在掘金337081 小时前
Redis 脚本速查
后端
姜九笙5611 小时前
python学习---归来仍是新人
java·python·学习
初见月1 小时前
适配器模式详解+对象透传治理
后端
HEJOO91 小时前
Java 并发运行中的安全问题详解
java·开发语言
2601_962106641 小时前
【无标题】
java·idea