因此,您想将事件调度到其当前状态的处理程序。
要调度到当前状态,在每个状态变为活动状态时对其进行订阅,而在其变为非活动状态时对其进行取消订阅则非常麻烦。订阅知道活动状态的对象比较容易,只需将所有事件委托给活动状态即可。
要区分事件,可以使用单独的事件对象,然后使用visitor模式来区分它们,但这是很多样板代码。仅当我有其他代码将所有事件都视为相同时(例如,如果事件必须在交付前进行缓冲),我才会这样做。否则,我只会做类似的事情
interface StateEventListener { void onEventX(); void onEventY(int x, int y); void onEventZ(String s);}enum State implements StateEventListener { initialState { @Override public void onEventX() { // do whatever } // same for other events }, // same for other states}class StateMachine implements StateEventListener { State currentState; @Override public void onEventX() { currentState.onEventX(); } @Override public void onEventY(int x, int y) { currentState.onEventY(x, y); } @Override public void onEventZ(String s) { currentState.onEventZ(s); }}编辑
如果事件类型很多,最好在运行时使用字节码工程库甚至是普通的JDK代理生成无聊的委托代码:
class StateMachine2 { State currentState; final StateEventListener stateEventPublisher = buildStateEventForwarder(); StateEventListener buildStateEventForwarder() { Class<?>[] interfaces = {StateEventListener.class}; return (StateEventListener) Proxy.newProxyInstance(getClass().getClassLoader(), interfaces, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { return method.invoke(currentState, args); } catch (InvocationTargetException e) { throw e.getCause(); } } }); }}这使代码的可读性较差,但确实消除了为每种事件类型编写委派代码的需要。



