13

更新:

状态模式可能是解决此问题的错误方法。因此,欢迎任何其他模式。基本上,我正在寻找一种方法来为每个状态设置保护条件,同时拥有干净且可维护的代码。如果不满足条件,前端路由系统(如 emberjs、ui-router 和 react-router)将如何实现guard conditions以避免进入特定状态?


我想通过使用状态模式来实现一个有限状态机,但我无法理解它。简而言之,它就像:

If error -> error state
If A && B && C -> second state
If only A -> first state

在任何状态下,一旦出错,我们就会进入错误状态。输入(事件)A、B 和 C 可能以任何顺序到达,但如果它们都通过,我们将进入第二状态。如果只有输入 A 适用,那么我们进入第一个状态。

以下状态图取自 Martin Fowler 的领域特定语言一书。

DSL

在描述中他说:

格兰特小姐,在她的卧室里有一个秘密隔间,通常是上锁和隐藏的。要打开它,她必须先关上门,然后打开她胸前的第二个抽屉,然后按任意顺序打开床头灯。一旦完成这些,秘密面板就会解锁,让她打开。

我强调,这turning light可以opening 2nd drawer任何顺序发生。与 A、B、C 相同。

根据@SQLPolice 评论和书,我画了这个:

在此处输入图像描述

但问题是,我可能有(A && B && C && D && D && E)。在那种情况下,拥有所有组合的临时状态会很麻烦。

4

3 回答 3

4

您可以为此使用某种形式的词法分析。我会通过限制从一个状态转换的能力来解决这个问题,除非满足两个状态之间的边缘上的约束。我最近用 PHP 为 Laravel 框架编写了一个 FSM,其中有一个示例,例如,在发生转换之前,各种约束都必须为真。它使用状态中的伪状态或句柄来切换表示进程已完成的标志。只有当所有标志都设置为 true 时,才能进行状态转换。

样本词汇状态分析

使用我为 laravel 编写的 FSM 包,示例 FSM 设置看起来像这样

每个状态都会(onEnter)或通过伪状态将其在 FSM OR 状态上的约束标志设置为 true。

这也将触发一个checkReady()基于约束标志触发转换或保持当前状态的事件。

添加新约束是将它们添加到状态或包含 FSM 内的约束数组中,并构建一种方法以允许在执行任务时删除约束。

当您查看多个状态时,每个状态都形成对约束的要求。 示例状态看起来像这样。

当您查看具有伪状态/处理程序的单个状态时。 状态看起来像这样,其中包含它的逻辑。

于 2015-07-01T09:39:24.647 回答
3

快速草稿如下所示:

在此处输入图像描述

于 2015-07-01T08:20:44.540 回答
1

状态机抽象包括:

  1. 状态
  2. 事件或输入
  3. 过渡
  4. 行动

像 a&&b&&c 这样的语句实际上是一个事件或输入……转换的标签。因此,如果您要适应状态机抽象,则需要将其映射到事件。您需要编写代码来执行该映射。

如果您的状态机通常由此类条件驱动,则您需要挂钩 ab 和 c 更改的事件,或者在计时器上定期检查它们。每当它们发生变化时,您的代码都会映射到一个事件并将它们发布到任何推进状态机的代码中。

于 2016-01-28T22:08:15.067 回答