场景:
我有一个简单的状态机:
快乐之路:
Uninitialized->Initialized->InProgress->Done
不幸的道路:
Uninitialized->Initialized->Error
简单地说,我需要在没有外部事件/触发器的情况下引起转换(进入 InProgress 或处于错误状态)。 IE。初始化状态应立即导致其中一种状态。
问题:
- 是否可以从 Initialized.Enter() 中引起状态转换?
- 我可以使用状态守卫来做到这一点,但我宁愿在状态守卫中没有非平凡的逻辑(并且初始化很可能很复杂)。
- 如果不行,我该如何做?
- 我是否应该将这个决定从 FSM 中取出,并让其他组件引起适当的转换?但是这样一来,我是否仍然需要从 Initialized.Enter() 中调用该外部组件?所以它解决不了任何问题?
最佳答案
在状态机中,下一状态是输入和当前状态的组合逻辑函数。
在您描述的情况下,相同的原因(Initialized
状态)似乎能够触发两种不同的效果(InProgress
或 Error
状态)。我猜想有一个隐藏的输入,其值会有所不同。我还猜测这个输入是在从 Uninitialized
到 Initialized
的转换过程中收到的。
因此我会有一个不同的模型:
Uninitialized -> Successfully initialized -> InProgress -> Done
\
`-> Failed Initialization -> Error
可能将 Successfully initialized
与 InProgress
和 Failed initialization
与 Error
结合。
编辑:根据您的评论,我了解到隐藏输入实际上是操作(设备初始化)的结果。采用您的模型,我假设初始化发生在 Initialized
状态(我们称之为 Initializing
)。这样,设备的结果就是您的外部事件,它将触发到 InProgress
或 Error
的转换。
因此保留您的状态机,并将 device.Initialize()
的结果简单地添加到输入或外部事件列表中。
关于状态机 : How to change state without external event (transient state)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/884081/