squirrel-foundation(松鼠状态机)简单介绍

498 阅读3分钟

本篇简单介绍下squirrel-foundation(松鼠状态机)了解的可以跳过。

if/else和switch对比

条件方式判断方式相对效率应用范围可读性
if/else逐级条件判断条件自由组合、万金油
switch跳跃式单一值匹配

其实本篇主题是记录下状态机(squirrel-foundation)的基本用法,难免不了要和内置的基本语法实现做比较,由于才疏学浅不知道该怎么简明扼要的描述它的优势。

明显的优势就是在语法和扩展性上直接带来的便捷;让水平不高的我也可以写出清晰优雅的代码。当然写业务前梳理完整的业务状态变换是必要的功课。

状态机可以使用条件分支判断、状态模式和基于DSL来实现,其中更具表达性的DSL也是很多开源状态机的实现方式。

squirrel-foundation(松鼠状态机)

squirrel-foundation有限状态机,我理解可以穷举业务流程状态了。非穷举的我到目前接触的是工作流通过xml描述流程。

image.png

通过这个图结合下面的入门的一些API调用可以更好的了解整个过程。

大概的过程分为:定义-》触发-》事件执行-》AOP(处理)-》异常处理

入门案例

StateMachine接口采用四个泛型类型参数。StateMachine<T, S, E, C>

参数解释
T代表已实现状态机的类型 ,, 也就是状态机本体
S代表实现状态的类型
E代表已实现事件的类型
C代表已实现的外部上下文的类型
  1. API声明式的流程声明
//事件定义
//状态也需要定义这里省略了
enum FSMEvent {
    ToA, ToB, ToC, ToD
}
//初始化定义 事件相应对应的方法声明StateMachineSample
UntypedStateMachineBuilder builder = StateMachineBuilderFactory.create(StateMachineSample.class);
//状态从A->B 事件 FSMEvent.ToB 对应的处理函数 fromAToB
builder.externalTransition().from("A").to("B").on(FSMEvent.ToB).callMethod("fromAToB");
//多了个过滤事件的控制when 里面的Condition是上下文传递的对象
builder.externalTransition().from("A").to("B").on(FSMEvent.ToB).when(new Condition<Object>() {
            @Override
            public boolean isSatisfied(Object o) {
                Integer test=(Integer) o;
                if(test.intValue()>5){
                    return true;
                }else {
                    return false;
                }
            }
            @Override
            public String name() {
                return null;
            }
        }).callMethod("fromAToB");
        
//当前状态为B时,进入状态B
builder.onEntry("B").callMethod("ontoB");        

2. 注解声明式的流程声明

@Transitions({
@Transit(from = "A", to = "B", on = "FSMEvent.ToB", callMethod = "fromAToB")
})

//@State定义每个状态,name状态名称,entry进入状态时调用的方法,exit 离开状态是调用的方法,initialState 为true时,为默认状态
@States({
@State(name = "FSMEvent.ToB", entryCallMethod = "entry", exitCallMethod = "exit", initialState = true)
})

3. 环绕事件:可以注解也可以覆盖实现方法 参考上面流程图

事件的环绕方法可以理解为AOP的操作,从下面支持的事件中可以看出还是很丰富的。

@OnTransitionBegin
@OnBeforeActionExecuted
@OnTransitionDecline
@OnActionExecException
@OnAfterActionExecuted
@OnTransitionComplete
@OnTransitionEnd
@OnTransitionException

4. 上面的都是约定,这里是使用的入口API

//状态A->B的流程触发
UntypedStateMachine fsm = builder.newStateMachine("A");
//6是上下文传递的对象 也可以不传递。实际使用的时候一般传的状态对应的单据对象 例如订单、审批、活动流程
fsm.fire(FSMEvent.ToB, 6);

缺点

  1. 单纯的第三方库,做web的话没有直接集成到spring中-》这里就引出了另一个问题就是想在状态转换过程中直接使用spirng的事务控制,网上看到的是拿到applicationContext采用了编程式事务。

最后提一点

对于一些主要数据的状态例如支付信息处理代码中的控制外,不会轻易手工处理的,这里有必要对数据库层面做一些触发器的约束,数据完整性可以用MD5进行处理。