基于 Java 枚举的状态机 (FSM):传入事件
我在我的Android应用程序中使用了几个基于枚举的状态机。虽然这些工作得很好,但我正在寻找的是有关如何优雅地接收事件(通常从已注册的回调或来自事件总线消息)到当前活动状态的建议。在关于基于枚举的FSM的许多博客和教程中,大多数都给出了使用数据的状态机(例如解析器)的示例,而不是展示这些FSM是如何从事件驱动的。
我使用的典型状态机具有以下形式:
private State mState;
public enum State {
SOME_STATE {
init() {
...
}
process() {
...
}
},
ANOTHER_STATE {
init() {
...
}
process() {
...
}
}
}
...
在我的情况下,某些状态会触发要在特定对象上完成的工作,注册侦听器。该对象在工作完成后异步回调。换句话说,只是一个简单的回调接口。
同样,我有一个事件总线。希望再次收到事件通知的类再次实现回调接口,并针对 EventBus 上的这些事件类型实现回调接口。listen()
因此,基本问题是状态机或其各个状态,或包含枚举 FSM 的类,或者其他什么东西必须实现这些回调接口,以便它们可以表示当前状态上的事件。
我使用的一种方法是整个实现回调接口。枚举本身在底部具有回调方法的默认实现,然后各个状态可以针对它们感兴趣的事件重写这些回调方法。为此,每个状态必须在进入和退出时注册和注销,否则存在回调发生在非当前状态的状态上的风险。如果我没有发现更好的,我可能会坚持下去。enum
另一种方法是让包含类实现回调。然后,它必须通过调用 来将这些事件委托给状态机。这意味着我需要枚举事件类型。例如:mState.process( event )
enum Events {
SOMETHING_HAPPENED,
...
}
...
onSometingHappened() {
mState.process( SOMETHING_HAPPENED );
}
然而,我不喜欢这样,因为(a)我需要在每个状态的事件类型上,并且(b)传递其他参数看起来很尴尬。switch
process(event)
我想要一个优雅的解决方案的建议,而不诉诸于使用库。