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.
简单地说,我需要在没有外部事件/触发器的情况下导致转换(进入InProgress或处于错误状态)。即初始化状态应立即导致其中一个状态。
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?
可以从Initialized.Enter()中导致状态转换吗?
我可以使用状态保护来做到这一点,但我宁愿在状态守卫中没有非平凡的逻辑(并且初始化很可能很复杂)。
如果不行,我该怎么做呢?
我是否应该一起从FSM中做出这个决定并让其他一些组件进行适当的转换?但是,我还不得不在Initialized.Enter()中调用该外部组件吗?所以什么都解决不了?
1 个解决方案
#1
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 (either InProgress
or Error
state). I guess that there is a hidden input whose value makes the difference. I also guess that this input is received during transition from Uninitialized
to Initialized
.
在您描述的情况下,相同的原因(初始化状态)似乎能够触发两种不同的效果(InProgress或Error状态)。我猜有一个隐藏的输入,其值有所不同。我还猜测在从未初始化到初始化的过渡期间接收到此输入。
Therefore I would have a different model:
因此我会有一个不同的模型:
Uninitialized -> Successfully initialized -> InProgress -> Done
\
`-> Failed Initialization -> Error
Possibly combining Successfully initialized
with InProgress
and Failed initialization
with Error
.
可能组合成功初始化与InProgress和失败初始化与错误。
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 it Initializing
). This way, the result from the device is your external event which will trigger transition either to InProgress
or to Error
.
编辑:从你的评论,我知道隐藏的输入实际上是一个动作(设备初始化)的结果。采用您的模型,我假设初始化发生在初始化状态(让我们称之为初始化)。这样,设备的结果就是外部事件,它将触发转换为InProgress或Error。
So keep your state machine and simply add the result of device.Initialize()
to the list of inputs or external events.
因此,请保留状态机,只需将device.Initialize()的结果添加到输入或外部事件列表中。
#1
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 (either InProgress
or Error
state). I guess that there is a hidden input whose value makes the difference. I also guess that this input is received during transition from Uninitialized
to Initialized
.
在您描述的情况下,相同的原因(初始化状态)似乎能够触发两种不同的效果(InProgress或Error状态)。我猜有一个隐藏的输入,其值有所不同。我还猜测在从未初始化到初始化的过渡期间接收到此输入。
Therefore I would have a different model:
因此我会有一个不同的模型:
Uninitialized -> Successfully initialized -> InProgress -> Done
\
`-> Failed Initialization -> Error
Possibly combining Successfully initialized
with InProgress
and Failed initialization
with Error
.
可能组合成功初始化与InProgress和失败初始化与错误。
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 it Initializing
). This way, the result from the device is your external event which will trigger transition either to InProgress
or to Error
.
编辑:从你的评论,我知道隐藏的输入实际上是一个动作(设备初始化)的结果。采用您的模型,我假设初始化发生在初始化状态(让我们称之为初始化)。这样,设备的结果就是外部事件,它将触发转换为InProgress或Error。
So keep your state machine and simply add the result of device.Initialize()
to the list of inputs or external events.
因此,请保留状态机,只需将device.Initialize()的结果添加到输入或外部事件列表中。