状态机:如何在没有外部事件的情况下改变状态(瞬态)?

发布于 2024-07-22 02:26:59 字数 642 浏览 1 评论 0原文

场景:
我有一个简单的状态机:

快乐路径:

Uninitialized->Initialized->InProgress->Done

不快乐路径:

Uninitialized->Initialized->Error

简而言之,我需要引起转换(进入 InProgress 或错误状态)没有外部事件/触发器。 即初始化状态应立即导致这些状态之一。

问题:

  1. 可以在 Initialized.Enter() 内引起状态转换吗?
  2. 我可以使用状态防护来做到这一点,但我不想在状态防护中使用不平凡的逻辑(并且初始化很可能很复杂)。
  3. 如果不行,我该如何做?
  4. 我是否应该从 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:

  1. Is it OK to cause state transition from within Initialized.Enter() ?
  2. 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).
  3. If it is NOT OK, how can I do it differently?
  4. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一个人的夜不怕黑 2024-07-29 02:26:59

在状态机中,下一个状态是输入和当前状态的组合逻辑函数。

在您描述的情况下,相同的原因(Initialized 状态)似乎能够触发两种不同的效果(InProgressError 状态)。 我猜想有一个隐藏的输入,其值会产生影响。 我还猜测此输入是在从 Uninitialized 转换到 Initialized 期间收到的。

因此,我会有一个不同的模型:

Uninitialized -> Successfully initialized -> InProgress -> Done
             \
              `-> Failed Initialization -> Error

可能将成功初始化InProgress结合起来,将失败初始化错误结合起来。


编辑:从您的评论中,我了解到隐藏的输入实际上是操作(设备初始化)的结果。 对于您的模型,我假设初始化是在 Initialized 状态下进行的(我们称之为 Initializing)。 这样,设备的结果就是您的外部事件,它将触发转换为 InProgressError

因此,保留状态机并将 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 (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.

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.


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.

So keep your state machine and simply add the result of device.Initialize() to the list of inputs or external events.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文