Coup de Grace

Easy系列 状态机源码解读

j-easy系列

这哥们的水平相当不错,不过可能是社区驱动型的…

没人提 enhancement 就做成1000行左右的玩具就不继续下去了

起个名字叫 paper actualizer 好了.

热衷 MIT License 真是个好人啊.

不过我是 WTFPL 的圣人(斜眼


状态机

废话不多说,抽象如下:

State(S) x Event(E) -> Actions(A), State(S')

简易用法

State locked = new State("locked");
State unlocked = new State("unlocked");

Set<State> states = new HashSet<State>();
states.add(locked);
states.add(unlocked);

class PushEvent extends Event { }
class CoinEvent extends Event { }

Transition unlock = new TransitionBuilder()
        .name("unlock")
        .sourceState(locked)
        .eventType(CoinEvent.class)
        .eventHandler(new Unlock())
        .targetState(unlocked)
        .build();

Transition lock = new TransitionBuilder()
        .name("lock")
        .sourceState(unlocked)
        .eventType(PushEvent.class)
        .eventHandler(new Lock())
        .targetState(locked)
        .build();

FiniteStateMachine turnstileStateMachine = new FiniteStateMachineBuilder(states, locked)
        .registerTransition(lock)
        .registerTransition(unlock)
        .build();

实现

一千行左右,不要指望它对各种场景有优化,不过也给了各种意义下的自由.

抽象:

Builder: 略

默认实现:

TransitionImpl:

//另外重写了 Object 几个方法.
final class TransitionImpl implements Transition {

    private String name;
    private State sourceState;
    private State targetState;
    private Class eventType;
    private EventHandler eventHandler;
}    

FiniteStateMachineImpl:

final class FiniteStateMachineImpl implements FiniteStateMachine {

    private State currentState;
    private State initialState;
    private Set<State> finalStates;
    private Set<State> states;
    private Set<Transition> transitions;
    private Event lastEvent;
    private Transition lastTransition;

    public final synchronized State fire(final Event event) throws FiniteStateMachineException {

        for (Transition transition : transitions) {
            if (
                // && 是阻塞操作,所以这样筛选出对应该 event 的transition
                currentState.equals(transition.getSourceState()) && 
                transition.getEventType().equals(event.getClass()) && 
                states.contains(transition.getTargetState()) 
                ) {
                if (transition.getEventHandler() != null) {
                    transition.getEventHandler().handleEvent(event);
                }
                currentState = transition.getTargetState();
                //save last triggered event and transition
                lastEvent = event;
                lastTransition = transition;

                break;
            }
        }
        return currentState;
    }
}

tips

其实我更关心状态机在以下情况下的表现:


done.