Java中状态机

状态机介绍

状态机(State Machine)是一种数学模型,用于描述对象或系统在不同状态之间的转移和行为。它由一组状态、转移条件和动作组成,可以根据输入条件从一个状态转移到另一个状态,并执行相应的动作。

特点:

  1. 离散性:状态机是离散的,它的状态和转移是离散的,不涉及连续变化。
  2. 易于理解和建模:状态机可以直观地描述对象或系统的行为,使得人们能够更好地理解和建模复杂的逻辑。
  3. 可扩展性:状态机可以轻松地添加新的状态和转移,以适应需求的变化。
  4. 灵活性:状态机可以根据输入条件自动转移状态,并执行相应的动作,具有较高的灵活性和自动化能力。

使用场景:

  1. 控制流程管理:状态机可以用于控制流程中的状态转移,例如工作流程管理、订单状态管理等。
  2. 设备控制:状态机可以用于描述设备的状态和状态转移,例如自动售货机、电梯控制等。
  3. 游戏开发:状态机可以用于游戏中的角色状态管理,例如角色的移动、攻击、防御等状态。
  4. 自动化系统:状态机可以用于自动化系统中的控制和决策,例如智能家居系统、工业自动化等。

总之,状态机是一种强大的工具,在一些较复杂的场景下可以帮助我们描述和管理对象或系统的状态和行为,提高代码的可理解性、可扩展性和灵活性。

状态机实现

一般情况下,都是使用状态模式:可以使用状态模式来实现状态机,将每个状态封装成一个类,通过状态之间的转换来实现状态机的功能,有点类似于策略模式。

状态机中一般包含状态(state)以及行为(handle),通过行为改变状态,并且此行为的结果是已知的。

案例:假设需要开发一套流程,其中,

状态:待处理、处理中、已处理、已评价。

行为:创建、分配、领取、流转、跟进、办结、评价。

具体的状态流转是:

行为 前置状态 后置状态
创建 待处理
分配 待处理 处理中
领取 待处理 处理中
流转 处理中 处理中
跟进 处理中 处理中
办结 处理中 已处理
评价 已处理 已评价

其实,从上面表格中也可以看出,行为和状态之间必然的联系,换成模型的话,可以用一个二维数组来表示,一维数组下标表示行为,二位数组下标表示前置状态,数组中的值表示后置状态。

使用表格表示:

创建 分配 领取 流转 跟进 办结 评价
待处理 × 处理中 处理中 × × × ×
处理中 × × × 处理中 处理中 已处理 ×
已处理 × × × × × × 已评价
已评价 × × × × × × ×

具体代码实现:

java 复制代码
public enum StatusEnum {
    PENDING("待处理"),
    PROCESSING("处理中"),
    PROCESSED("已处理"),
    EVALUATED("已评价");

    private String name;

    StatusEnum(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}
java 复制代码
public enum ActionEnum {

    CREATE("创建"),
    ASSIGN("分配"),
    RECEIVE("领取"),
    TRANSFER("流转"),
    FOLLOW_UP("跟进"),
    FINISH("办结"),
    EVALUATE("评价");

    private String name;

    ActionEnum(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}
java 复制代码
/**
 * 状态机
 */
public class StateMachine {

    private static final StatusEnum[][] transitions = {
            {null,StatusEnum.PROCESSING,StatusEnum.PROCESSING,null,null,null,null},
            {null,null,null,StatusEnum.PROCESSING,StatusEnum.PROCESSING,StatusEnum.PROCESSED,null},
            {null,null,null,null,null,null,StatusEnum.EVALUATED},
            {null,null,null,null,null,null,null}
    };

    public StatusEnum handle(StatusEnum status, ActionEnum action) {
        int statusIndex = status.ordinal();
        int actionIndex = action.ordinal();
        StatusEnum nextStatus = transitions[statusIndex][actionIndex];
        if (nextStatus == null) {
            throw new IllegalStateException("no valid action");
        }
        return nextStatus;
    }
}

测试代码:

java 复制代码
public class StateMachineTest {

    public static void main(String[] args) {
        StateMachine stateMachine = new StateMachine();
        // 当前状态待处理,操作是分配,得出下一步状态是处理中
        System.out.println(stateMachine.handle(StatusEnum.PENDING, ActionEnum.ASSIGN));

        // 当前状态已处理,操作是分配,为null,即操作不当
        System.out.println(stateMachine.handle(StatusEnum.PROCESSED, ActionEnum.ASSIGN));
    }
}

测试结果:

java 复制代码
PROCESSING
Exception in thread "main" java.lang.IllegalStateException: no valid action
	at com.honor.wpshowdemo.serverone.example.StateMachine.handle(StateMachine.java:17)
	at com.honor.wpshowdemo.serverone.example.StateMachineTest.main(StateMachineTest.java:11)
相关推荐
Wang15301 小时前
jdk内存配置优化
java·计算机网络
0和1的舞者2 小时前
Spring AOP详解(一)
java·开发语言·前端·spring·aop·面向切面
Wang15302 小时前
Java多线程死锁排查
java·计算机网络
小小星球之旅2 小时前
CompletableFuture学习
java·开发语言·学习
jiayong233 小时前
知识库概念与核心价值01
java·人工智能·spring·知识库
皮皮林5513 小时前
告别 OOM:EasyExcel 百万数据导出最佳实践(附开箱即用增强工具类)
java
Da Da 泓4 小时前
多线程(七)【线程池】
java·开发语言·线程池·多线程
To Be Clean Coder4 小时前
【Spring源码】getBean源码实战(三)
java·mysql·spring
Wokoo74 小时前
开发者AI大模型学习与接入指南
java·人工智能·学习·架构
电摇小人5 小时前
我的“C++之旅”(博客之星主题作文)
java·开发语言