状态机(有限状态机)的概念
状态机(state machine)是一种抽象的模型,用来描述一个对象或系统在不同状态下的行为和状态转换。它由一组状态、一组事件和一组转换规则组成。
当某个事件发生时,状态机根据当前的状态和事件,执行相应的动作,并转移到下一个状态。
具体而言,一个有限状态机包含以下几个要素:
状态(State):表示对象或系统的不同状态。在JAVA中,状态通常是由一个枚举类型定义的。
事件(Event):表示导致状态转换的事件。事件可以是外部输入、用户行为等。
转换规则(Transition):表示状态之间的转换条件和动作。转换规则由当前状态、事件和下一个状态组成。
java中的状态机实现
如果使用if-else语句、switch语句等。然而,这些方式在处理复杂的状态转换时往往会导致代码冗长、可读性差等问题。
实现状态机可以帮助我们更好地管理对象的状态变化,提高代码的可读性和可维护性。
开源实现:
spring-statemachine、squirrel-foundation、sateless4j等。其中spring-statemachine、squirrel-foundation在github上star和fock数稳居前二。
优缺点
开源状态机 | 优点 | 缺点 |
---|---|---|
squirrel-foundation | 1、轻量级,代码清晰,文档详细,扩展和维护性好 2、支持声明式和编程式编程。 3、支持异步和延时事件,可自定义线程池。 4、StateMachine实例创建开销小,单例复用的生命流管理更清晰,避免复用产生死锁。 |
代码太过于约定大于配置 |
spring-statemachine | 加强版squirrel,功能很全 | 相对比较重 |
sateless4j | 1、十分轻量级的实现,比squireel还要精简,代码量很少 2、二次开发难度低 |
本身支持的action少,导致扩展很有限 |
squirrel-foundation:https://github.com/hekailiang/squirrel
squirrel-foundation
状态机引擎
public interface StateMachine<T extends StateMachine<T, S, E, C>, S, E, C>
StateMachine 接口需要以下 4 种泛型参数。
T 代表实现的状态机类型。(定义自己的状态机类,需继承AbstractStateMachine)
S 代表实现的状态类型。 (定义业务状态枚举)
E 代表实现的事件类型。 (定义业务事件枚举)
C 代表实现的外部上下文类型。 (参数上下文)
1、创建状态机
StateMachineBuilder<...> builder = StateMachineBuilderFactory.create(
MyStateMachine.class, MyState.class, MyEvent.class, MyContext.class);
builder.externalTransition().from(A).to(B).on(toB).callMethod("fromAToB");
2、创建新状态机实例
MyStateMachine stateMachine = builder.newStateMachine(MyState.Initial);
3、可以触发事件以及上下文来触发状态机内的转换。
stateMachine.fire(MyEvent.Prepare, new MyContext("Testing"));
注意:由于StateMachine实例不是由Spring容器创建,所以这个过程中无法通过注解方式开启事务,因此采用了编程式事务
DataSourceTransactionManager transactionManager = (DataSourceTransactionManager)applicationContext.getBean("transactionManager");
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = transactionManager.getTransaction(def);
支持的高阶功能有:状态的嵌套(substate),状态的并行(parallel,fork,join)、子状态机等等。