一. 设计思路
1.1 状态机领域模型
State:状态
Event:事件,状态由事件触发,引起变化
Transition:流转,表示从一个状态到另一个状态
External Transition:外部流转,两个不同状态之间的流转
Internal Transition:内部流转,同一个状态之间的流转
Condition:条件,表示是否允许到达某个状态
Action:动作,到达某个状态之后,可以做什么
StateMachine:状态机
1.2 细节设计
一个起始状态和一个事件唯一确定一个目标状态
一个起始状态经过不同事件可以流转到同一状态或不同状态
二. 使用方法
2.1 外部流转
@Test
public void testExternalNormal() {
StateMachineBuilder<States, Events, Context> builder = StateMachineBuilderFactory.create();
builder.externalTransition()
.from(States.STATE1)
.to(States.STATE2)
.on(Events.EVENT1)
.when(checkCondition())
.perform(doAction());
StateMachine<States, Events, Context> stateMachine = builder.build(MACHINE_ID);
States target = stateMachine.fireEvent(States.STATE1, Events.EVENT1, new Context());
Assert.assertEquals(States.STATE2, target);
}
2.2 内部流转
@Test
public void testInternalNormal() {
StateMachineBuilder<States, Events, Context> builder = StateMachineBuilderFactory.create();
builder.internalTransition()
.within(States.STATE1)
.on(Events.INTERNAL_EVENT)
.when(checkCondition())
.perform(doAction());
StateMachine<States, Events, Context> stateMachine = builder.build(MACHINE_ID + "2");
stateMachine.fireEvent(States.STATE1, Events.EVENT1, new Context());
States target = stateMachine.fireEvent(States.STATE1, Events.INTERNAL_EVENT, new Context());
Assert.assertEquals(States.STATE1, target);
}
2.3 条件流转
@Test
public void testChoice(){
StateMachineBuilder<StateMachineTest.States, StateMachineTest.Events, Context> builder = StateMachineBuilderFactory.create();
builder.internalTransition()
.within(StateMachineTest.States.STATE1)
.on(StateMachineTest.Events.EVENT1)
.when(checkCondition1())
.perform(doAction());
builder.externalTransition()
.from(StateMachineTest.States.STATE1)
.to(StateMachineTest.States.STATE2)
.on(StateMachineTest.Events.EVENT1)
.when(checkCondition2())
.perform(doAction());
builder.externalTransition()
.from(StateMachineTest.States.STATE1)
.to(StateMachineTest.States.STATE3)
.on(StateMachineTest.Events.EVENT1)
.when(checkCondition3())
.perform(doAction());
StateMachine<StateMachineTest.States, StateMachineTest.Events, Context> stateMachine = builder.build("ChoiceConditionMachine");
StateMachineTest.States target1 = stateMachine.fireEvent(StateMachineTest.States.STATE1, StateMachineTest.Events.EVENT1, new Context("1"));
Assert.assertEquals(StateMachineTest.States.STATE1,target1);
StateMachineTest.States target2 = stateMachine.fireEvent(StateMachineTest.States.STATE1, StateMachineTest.Events.EVENT1, new Context("2"));
Assert.assertEquals(StateMachineTest.States.STATE2,target2);
StateMachineTest.States target3 = stateMachine.fireEvent(StateMachineTest.States.STATE1, StateMachineTest.Events.EVENT1, new Context("3"));
Assert.assertEquals(StateMachineTest.States.STATE3,target3);
}
2.4 多对一流转
/**
* 取消订单: 待支付、待发货、待收货 -> 待支付
* externalTransitions : 用于多个流转的构建器
*/
builder.externalTransitions()
.fromAmong(OrderStatusEnum.PAY_ONLINE,OrderStatusEnum.WAITING_FOR_RECEIVED,OrderStatusEnum.WAITING_DELIVERY)
.to(OrderStatusEnum.CANCEL)
.on(OrderEventEnum.CANCEL_ORDER)
.when(checkOrder())
.perform(cancelOrderAction);