參考鏈接:http://hekailiang.github.io/squirrel/
Squirrel使用 | 城的燈
介紹
squirrel-foundation:輕量級(jí)java有限狀態(tài)機(jī)
狀態(tài)機(jī)的要素
狀態(tài)機(jī)可歸納為4個(gè)要素,即現(xiàn)態(tài)、條件、動(dòng)作、次態(tài)?!艾F(xiàn)態(tài)”和“條件”是因,“動(dòng)作”和“次態(tài)”是果。
現(xiàn)態(tài):是指當(dāng)前所處的狀態(tài)。
條件:又稱為事件。當(dāng)一個(gè)條件被滿足,將會(huì)觸發(fā)一個(gè)動(dòng)作,或者執(zhí)行一次狀態(tài)的遷移。
動(dòng)作:條件滿足后執(zhí)行的動(dòng)作。動(dòng)作執(zhí)行完畢后,可以遷移到新的狀態(tài),也可以仍舊保持原狀態(tài)。動(dòng)作不是必需的,當(dāng)條件滿足后,也可以不執(zhí)行任何動(dòng)作,直接遷移到新狀態(tài)。
次態(tài):條件滿足后要遷往的新狀態(tài)?!按螒B(tài)”是相對(duì)于“現(xiàn)態(tài)”而言的,“次態(tài)”一旦被激活,就轉(zhuǎn)變成新的“現(xiàn)態(tài)”了。
入門級(jí)Demo
導(dǎo)入依賴
<dependency>
<groupId>org.squirrelframework</groupId>
<artifactId>squirrel-foundation</artifactId>
<version>0.3.8</version>
</dependency>
StateMachine接口需要以下4種泛型參數(shù)。
T代表實(shí)現(xiàn)的狀態(tài)機(jī)類型。
S代表實(shí)現(xiàn)的狀態(tài)類型。
E代表實(shí)現(xiàn)的事件類型。
C代表實(shí)現(xiàn)的外部上下文類型。
定義S:即狀態(tài)類型
public enum MyState {
A,
B,
C,
D;
}
定義E:即事件類型
public enum MyEvent {
ToA,ToB,ToC,ToD;
}
定義C:即上下文類型,只有一個(gè)num字段
public class MyContext {
public int num = 0;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
}
定義T:狀態(tài)機(jī)類型
/**
* 定義我的狀態(tài)機(jī):需繼承AbstractStateMachine
*/
public class MyStateMachine extends AbstractStateMachine<MyStateMachine, MyState, MyEvent, MyContext> {
public void fun1(MyState from, MyState to, MyEvent event, MyContext context) {
System.out.println("fun1() 方法執(zhí)行了。。。。。。。。。。。。。 from:" + from + ", to:" + to +", event:" +event +", context:" + context.num );
}
}
編寫main函數(shù)
public static void main(String[] args) {
StateMachineBuilder<MyStateMachine, MyState, MyEvent, MyContext> builder =
StateMachineBuilderFactory.create(MyStateMachine.class, MyState.class, MyEvent.class, MyContext.class);
/**
* 條件為:content.getNum 為20的時(shí)候轉(zhuǎn)換,并執(zhí)行fun1()方法
*/
builder.externalTransition().from(MyState.A).to(MyState.B).on(MyEvent.ToB)
.whenMvel("myCondition:::(context!=null && context.getNum() == 20)").callMethod("fun1");
MyStateMachine machine = builder.newStateMachine(MyState.A);
machine.start();
System.out.println("currentState is " + machine.getCurrentState());
MyContext context = new MyContext();
context.setNum(20);
machine.fire(MyEvent.ToB, context);
System.out.println("currentState is " + machine.getCurrentState());
}
結(jié)果打印
currentState is A
fun1() 方法執(zhí)行了。。。。。。。。。。。。。 from:A, to:B, event:toB, context:20
currentState is B
添加監(jiān)聽和注解開發(fā)
修改T,增加監(jiān)聽
/**
* 定義我的狀態(tài)機(jī):需繼承AbstractStateMachine
*/
public class MyStateMachine extends AbstractStateMachine<MyStateMachine, MyState, MyEvent, MyContext> {
public void fun1(MyState from, MyState to, MyEvent event, MyContext context) {
System.out.println("fun1() 方法執(zhí)行了。。。。。。。。。。。。。 from:" + from + ", to:" + to + ", event:" + event + ", context:" + context.num);
}
/**
* 約定大于配置
* like:
* transitFrom[fromStateName]To[toStateName]On[eventName]When[conditionName]
* transitFrom[fromStateName]To[toStateName]On[eventName]
* transitFromAnyTo[toStateName]On[eventName]
* transitFrom[fromStateName]ToAnyOn[eventName]
* transitFrom[fromStateName]To[toStateName]
* on[eventName]
*/
protected void transitFromAToBOnToB(MyState from, MyState to, MyEvent event, MyContext context){
System.out.println("從A--->B執(zhí)行....約定大于配置");
}
/**
* exitA執(zhí)行
*/
protected void exitA(MyState from, MyState to, MyEvent event, MyContext context){
System.out.println("exitA()方法執(zhí)行了。。。。。。。。");
}
public class DeclarativeListener {
@OnTransitionBegin
public void transitionBegin(MyEvent event) {
// method annotated with TransitionBegin will be invoked when transition begin...
System.out.println("轉(zhuǎn)換開始執(zhí)行.." + event);
}
/**
* 條件:context.num == 20 || event.name().equals("toC")
*/
@OnTransitionBegin(when = "context.num == 20 || event.name().equals(\"toC\")")
public void begins(MyState from, MyState to, MyEvent event, MyContext context) {
System.out.println("begins 執(zhí)行了, from:" + from + ", to:" + to + ", event:" + event + ", context:" + context.num);
}
@OnTransitionEnd
@ListenerOrder(10) // Since 0.3.1 ListenerOrder can be used to insure listener invoked orderly
public void transitionEnd() {
// method annotated with TransitionEnd will be invoked when transition end...
// the method must be public and return nothing
System.out.println("轉(zhuǎn)換結(jié)束執(zhí)行..");
}
@OnTransitionComplete
public void transitionComplete(String from, String to, MyEvent event, Integer context) {
// method annotated with TransitionComplete will be invoked when transition complete...
System.out.println("轉(zhuǎn)換成功執(zhí)行..");
}
@OnTransitionDecline
public void transitionDeclined(String from, MyEvent event, Integer context) {
// method annotated with TransitionDecline will be invoked when transition declined...
System.out.println("轉(zhuǎn)換拒絕執(zhí)行..");
}
@OnBeforeActionExecuted
public void onBeforeActionExecuted(Object sourceState, Object targetState,
Object event, Object context, int[] mOfN, Action<?, ?, ?,?> action) {
// method annotated with OnAfterActionExecuted will be invoked before action invoked
System.out.println("狀態(tài)機(jī)內(nèi)方法動(dòng)作執(zhí)行之前...111111111111111111111111111111111");
}
@OnAfterActionExecuted
public void onAfterActionExecuted(Object sourceState, Object targetState,
Object event, Object context, int[] mOfN, Action<?, ?, ?,?> action) {
// method annotated with OnAfterActionExecuted will be invoked after action invoked
System.out.println("狀態(tài)機(jī)內(nèi)方法動(dòng)作執(zhí)行之后...222222222222222222222222222222222");
}
@OnActionExecException
public void onActionExecException(Action<?, ?, ?,?> action, TransitionException e) {
// method annotated with OnActionExecException will be invoked when action thrown exception
System.out.println("轉(zhuǎn)換異常執(zhí)行。。");
}
}
}
再次編寫Main函數(shù)
public static void main(String[] args) {
StateMachineBuilder<MyStateMachine, MyState, MyEvent, MyContext> builder =
StateMachineBuilderFactory.create(MyStateMachine.class, MyState.class, MyEvent.class, MyContext.class);
/**
* 條件為:content.getNum 為20的時(shí)候轉(zhuǎn)換,并執(zhí)行fun1()方法
*/
builder.externalTransition().from(MyState.A).to(MyState.B).on(MyEvent.ToB)
.whenMvel("myCondition:::(context!=null && context.getNum() == 20)").callMethod("fun1");
builder.externalTransition().from(MyState.A).to(MyState.C).on(MyEvent.ToC);
MyStateMachine machine = builder.newStateMachine(MyState.A);
machine.addDeclarativeListener(machine.new DeclarativeListener());
machine.start();
System.out.println("currentState is " + machine.getCurrentState());
MyContext context = new MyContext();
context.setNum(20);
machine.fire(MyEvent.ToB, context);
System.out.println("currentState is " + machine.getCurrentState());
}
結(jié)果打印
currentState is A
begins 執(zhí)行了, from:A, to:null, event:ToB, context:20
轉(zhuǎn)換開始執(zhí)行..ToB
狀態(tài)機(jī)內(nèi)方法動(dòng)作執(zhí)行之前...111111111111111111111111111111111
exitA()方法執(zhí)行了。。。。。。。。
狀態(tài)機(jī)內(nèi)方法動(dòng)作執(zhí)行之后...222222222222222222222222222222222
狀態(tài)機(jī)內(nèi)方法動(dòng)作執(zhí)行之前...111111111111111111111111111111111
fun1() 方法執(zhí)行了。。。。。。。。。。。。。 from:A, to:B, event:ToB, context:20
狀態(tài)機(jī)內(nèi)方法動(dòng)作執(zhí)行之后...222222222222222222222222222222222
狀態(tài)機(jī)內(nèi)方法動(dòng)作執(zhí)行之前...111111111111111111111111111111111
從A--->B執(zhí)行....約定大于配置
狀態(tài)機(jī)內(nèi)方法動(dòng)作執(zhí)行之后...222222222222222222222222222222222
轉(zhuǎn)換成功執(zhí)行..
轉(zhuǎn)換結(jié)束執(zhí)行..
currentState is B
不足之處,歡迎指正!謝謝!?