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)
相关推荐
cui_hao_nan3 小时前
JVM——如何对java的垃圾回收机制调优?
java·jvm
熟悉的新风景5 小时前
springboot项目或其他项目使用@Test测试项目接口配置-spring-boot-starter-test
java·spring boot·后端
心平愈三千疾5 小时前
学习秒杀系统-实现秒杀功能(商品列表,商品详情,基本秒杀功能实现,订单详情)
java·分布式·学习
玩代码5 小时前
备忘录设计模式
java·开发语言·设计模式·备忘录设计模式
BUTCHER56 小时前
Docker镜像使用
java·docker·容器
岁忧6 小时前
(nice!!!)(LeetCode 面试经典 150 题 ) 30. 串联所有单词的子串 (哈希表+字符串+滑动窗口)
java·c++·leetcode·面试·go·散列表
LJianK17 小时前
Java和JavaScript的&&和||
java·javascript·python
RealmElysia7 小时前
java反射
java·开发语言
野蛮人6号7 小时前
黑马点评系列问题之p63unlock.lua不知道怎么整
java·redis·黑马点评
Raners_8 小时前
【Java代码审计(2)】MyBatis XML 注入审计
xml·java·安全·网络安全·mybatis