状态机:如何在没有外部事件的情况下改变状态(瞬态)?
场景:
我有一个简单的状态机:
快乐路径:
Uninitialized->Initialized->InProgress->Done
不快乐路径:
Uninitialized->Initialized->Error
简而言之,我需要引起转换(进入 InProgress 或错误状态)没有外部事件/触发器。 即初始化状态应立即导致这些状态之一。
问题:
- 可以在 Initialized.Enter() 内引起状态转换吗?
- 我可以使用状态防护来做到这一点,但我不想在状态防护中使用不平凡的逻辑(并且初始化很可能很复杂)。
- 如果不行,我该如何做?
- 我是否应该从 FSM 中一起做出这个决定,并让其他一些组件导致适当的转换? 但是,我是否仍然需要从 Initialized.Enter() 内部调用该外部组件? 所以它什么也解决不了?
The scenario:
I have a simple state machine:
Happy path:
Uninitialized->Initialized->InProgress->Done
Unhappy path:
Uninitialized->Initialized->Error
Simply put, I need to cause a transition (either into InProgress or in Error state) without an external event/trigger. I.e. Initialized state should immediately result in one of those states.
Questions:
- Is it OK to cause state transition from within Initialized.Enter() ?
- I could use state guards to do this, but I'd rather not have non-trivial logic in the state guard (and initialization can very well be complex).
- If it is NOT OK, how can I do it differently?
- Should I just take this decision out of he FSM all together and have some other component cause the appropriate transition? But then, wouldn't I still have to call that external component from within Initialized.Enter() ? so it solves nothing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在状态机中,下一个状态是输入和当前状态的组合逻辑函数。
在您描述的情况下,相同的原因(
Initialized
状态)似乎能够触发两种不同的效果(InProgress
或Error
状态)。 我猜想有一个隐藏的输入,其值会产生影响。 我还猜测此输入是在从Uninitialized
转换到Initialized
期间收到的。因此,我会有一个不同的模型:
可能将
成功初始化
与InProgress
结合起来,将失败初始化
与错误
结合起来。编辑:从您的评论中,我了解到隐藏的输入实际上是操作(设备初始化)的结果。 对于您的模型,我假设初始化是在
Initialized
状态下进行的(我们称之为Initializing
)。 这样,设备的结果就是您的外部事件,它将触发转换为InProgress
或Error
。因此,保留状态机并将
device.Initialize()
的结果添加到输入或外部事件列表中。In a state machine, next state is a combinatorial logic function of both input and current state.
In the case you are describing, the same cause (
Initialized
state) seems to be able to trigger two different effects (eitherInProgress
orError
state). I guess that there is a hidden input whose value makes the difference. I also guess that this input is received during transition fromUninitialized
toInitialized
.Therefore I would have a different model:
Possibly combining
Successfully initialized
withInProgress
andFailed initialization
withError
.EDIT: From your comment, I understand that the hidden input actually is the result of an action (a device initialization). Taking your model, I assume that initialization takes place while in
Initialized
state (let's call itInitializing
). This way, the result from the device is your external event which will trigger transition either toInProgress
or toError
.So keep your state machine and simply add the result of
device.Initialize()
to the list of inputs or external events.