放在前面的一些介绍🤖
这部分了解的朋友可以跳过,直接上手后面的代码( ̄∇ ̄)/
Squirrel-Foundation 🆚 StatusMachine
Squirrel-Foundation和StatusMachine都是Java状态机框架,用于实现状态机模式,它们的主要区别有以下4点:
-
语法和API
-
Squirrel-Foundation使用类似于DSL的语法和函数式API,而StatusMachine使用基于注解的方式来定义状态和转换,两者在语法和API上有较大的差异。
-
DSL
- DSL的全称是“Domain Specific Language”,即领域特定语言。它是一种用于特定领域的编程语言,通常具有更加简单、清晰和易于理解的语法和API,能够提高代码的可读性和可维护性。DSL的语法和API通常会针对具体的问题领域进行优化,以便更加贴合领域的需求。
-
函数式API
- 函数式API是一种编程范式,它将函数作为一等公民,允许将函数作为参数传递、返回值或者赋值给变量,从而实现代码的复用和组合。函数式API通常具有不可变性、高阶函数、Lambda表达式等特性,能够提高代码的可读性、可维护性和性能。
-
在Java中,DSL的语法和函数式API通常用于实现流畅接口(Fluent Interface)和方法链式调用(Method Chaining),以提高代码的简洁性和可读性。
-
功能
- Squirrel-Foundation提供了更加丰富的功能,如状态机持久化、异步事件处理、状态机层次结构等,而StatusMachine则更加注重简单易用,功能相对较少。
-
兼容性
- Squirrel-Foundation支持JDK 1.6及以上版本,可以在Java SE和Android应用中使用
- StatusMachine仅支持JDK 1.8及以上版本,不能在低版本的Java应用中使用。
-
社区支持
-
相比StatusMachine来说,Squirrel-Foundation的社区更为活跃,有广泛的文档和教程可供参考
-
保姆级Demo
作为一个☝️保姆级博文选手,附上完整可执行的代码是一项基本素质
-
添加依赖🌵
<!-- 状态机 -->
<dependency>
<groupId>org.squirrelframework</groupId>
<artifactId>squirrel-foundation</artifactId>
<version>0.3.8</version>
<!-- 可能会出现冲突的jar,如果项目中没有引入一下几类可忽略<exclusions>的部分-->
<exclusions>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
</exclusions>
</dependency>
-
示例代码
下面这段代码是从官网的QuickStartSample改的(嘿嘿类名都没变(˶‾᷄ ⁻̫ ‾᷅˵))
public class QuickStartSample {
enum TrafficLightEvent {
GREEN_TO_YELLOW, YELLOW_TO_RED, RED_TO_GREEN, REPAIRED
}
enum TrafficLightState {
GREEN, YELLOW, RED, OFF
}
@StateMachineParameters(stateType = TrafficLightState.class, eventType = TrafficLightEvent.class, contextType = Void.class)
static class TrafficLightMachine extends AbstractUntypedStateMachine {
/***
* the method be invoke when status changes
* @param from
* @param to
* @param event
* @param context
*/
protected void changeFromGreenToYellow(TrafficLightState from, TrafficLightState to, TrafficLightEvent event, Void context) {
System.out.println("Traffic light changed from " + from + " to " + to);
}
protected void changeFromYellowToRed(TrafficLightState from, TrafficLightState to, TrafficLightEvent event, Void context) {
System.out.println("Traffic light changed from " + from + " to " + to);
}
protected void changeFromRedToGreen(TrafficLightState from, TrafficLightState to, TrafficLightEvent event, Void context) {
System.out.println("Traffic light changed from " + from + " to " + to);
}
protected void repair(TrafficLightState from, TrafficLightState to, TrafficLightEvent event, Void context) {
System.out.println("Traffic light needs repaired!");
}
}
public static void main(String[] args) {
UntypedStateMachineBuilder builder = StateMachineBuilderFactory.create(TrafficLightMachine.class);
builder.externalTransition().from(TrafficLightState.GREEN).to(TrafficLightState.YELLOW).on(TrafficLightEvent.GREEN_TO_YELLOW).callMethod("changeFromGreenToYellow");
builder.externalTransition().from(TrafficLightState.YELLOW).to(TrafficLightState.RED).on(TrafficLightEvent.YELLOW_TO_RED).callMethod("changeFromYellowToRed");
builder.externalTransition().from(TrafficLightState.RED).to(TrafficLightState.GREEN).on(TrafficLightEvent.RED_TO_GREEN).callMethod("changeFromRedToGreen");
builder.externalTransition().from(TrafficLightState.RED).to(TrafficLightState.OFF).on(TrafficLightEvent.REPAIRED).callMethod("repair");
builder.onEntry(TrafficLightState.OFF).callMethod("repair");
UntypedStateMachine myStateMachine = builder.newStateMachine(TrafficLightState.GREEN);
myStateMachine.start();
myStateMachine.fire(TrafficLightEvent.GREEN_TO_YELLOW);
myStateMachine.fire(TrafficLightEvent.YELLOW_TO_RED);
myStateMachine.fire(TrafficLightEvent.RED_TO_GREEN);
myStateMachine.fire(TrafficLightEvent.REPAIRED);
System.out.println("Current state is " + myStateMachine.getCurrentState());
myStateMachine.terminate();
}
}
着急的朋友添加了依赖,直接新建一个同名类(QuickStartSample
),把👆上面的代码直接copy进去,就可以看到执行结果叻
补充说明
状态机四要素
QuickStartSample 中体现在如下
@StateMachineParameters(stateType=String.class, eventType=FSMEvent.class, contextType=Integer.class)
static class StateMachineSample extends AbstractStateMachine<MyStateMachine , FSMState , FSMEvent , Integer>
StateMachine接口采用四个泛型类型参数。
StateMachine<T, S, E, C> ,
ps : 要是想看这几个状态的可以向上找下 AbstractStateMachine 关系如下 👇
MyStateMachine
extends AbstractUntypedStateMachine
AbstractUntypedStateMachine
extends AbstractStateMachine
T
-代表已实现状态机的类型 ,, 也就是状态机本体。
S
-代表实现状态的类型 。
E
-代表已实现事件的类型。
C
-代表已实现的外部上下文的类型。
在QuickStartSample
中体现在如下
StateMachineBuilder<MyStateMachine, MyState, MyEvent, MyContext> builder =
StateMachineBuilderFactory.create(MyStateMachine.class, MyState.class, MyEvent.class, MyContext.class);
为了创建状态机,用户需要先创建状态机构建器
本文主要参考官方教程(hekailiang.github.io/squirrel/ )