(1). 概述
前面对State和Transition进行了源码分析,其实,这两个类是数据的载体,属于业务模型的了解,这一小篇主要剖析的是:StateMachine,在进行StateMachine源码剖析之前,还是一样,先看下接口的职责能力范围.
(2). StateMachine
public interface StateMachine<S, E, C> extends Visitable{
// **************************************************
// 触发事件
// **************************************************
S fireEvent(S sourceState, E event, C ctx);
String getMachineId();
void showStateMachine();
String generatePlantUML();
}
(3). StateMachineImpl
public class StateMachineImpl<S, E, C> implements StateMachine<S, E, C> {
private String machineId;
// 通过Map收集了所有的State,所以,State是不能重复的,因为是key.
private final Map<S, State<S, E, C>> stateMap;
private boolean ready;
public StateMachineImpl(Map<S, State<S, E, C>> stateMap) {
this.stateMap = stateMap;
}
@Override
public S fireEvent(S sourceStateId, E event, C ctx) {
// 1. 检查一把
isReady();
// *************************************************************
// 2. 根据当前状态(State+Event),找出一个:Transition
// *************************************************************
Transition<S, E, C> transition = routeTransition(sourceStateId, event, ctx);
if (transition == null) {
Debugger.debug("There is no Transition for " + event);
return sourceStateId;
}
// *************************************************************
// 3. 执行Transition.transit
// 在第一步的源码里就剖析了,就是执行action.
// *************************************************************
return transition.transit(ctx, false).getId();
}
// *************************************************************
// 2.1 根据当前状态枚举字符串,获得:State对象
// 在State对象里又拥有这个State所有的Transition,根据Event过滤出相应的Event,遍历符合条件的:Transition,执行用户配置的condition.
// *************************************************************
private Transition<S, E, C> routeTransition(S sourceStateId, E event, C ctx) {
State sourceState = getState(sourceStateId);
List<Transition<S, E, C>> transitions = sourceState.getEventTransitions(event);
if (transitions == null || transitions.size() == 0) {
return null;
}
Transition<S, E, C> transit = null;
for (Transition<S, E, C> transition : transitions) {
if (transition.getCondition() == null) {
transit = transition;
} else if (transition.getCondition().isSatisfied(ctx)) { // 执行自定义配置的condition.
transit = transition;
break;
}
}
return transit;
}
// ***************************************************************
// 根据当前的状态枚举,获得State对象,因为:State对象里存储着:Transition
// ***************************************************************
private State getState(S currentStateId) {
State state = StateHelper.getState(stateMap, currentStateId);
if (state == null) {
showStateMachine();
throw new StateMachineException(currentStateId + " is not found, please check state machine");
}
return state;
} // end
}
(4). 总结
总体来说,阿里开源的COLA相比Spring StateMachine比较简单和易懂,阿里开源一向的习惯是:当你看到模型的时候,相应的接口能力就出来了的,没那么多的花花肠子来着的(能够证明一件事情,阿里开源时,早就做好了类设计).