Design patterns 国家模式与防范

Design patterns 国家模式与防范,design-patterns,state-machine,state-pattern,state-diagram,Design Patterns,State Machine,State Pattern,State Diagram,更新: 状态模式可能是解决此问题的错误方法。因此,任何其他模式都是受欢迎的。基本上,我正在寻找一种方法,既能为每个状态提供保护条件,又能提供干净且可维护的代码。如emberjs、ui路由器和react路由器等前端侧路由系统如何实现保护条件,以避免在不满足条件时进入特定状态 我想通过使用状态模式来实现一个有限状态机,但我不能对它掉以轻心。简言之,这就像: If error -> error state If A && B && C -> second

更新:

状态模式可能是解决此问题的错误方法。因此,任何其他模式都是受欢迎的。基本上,我正在寻找一种方法,既能为每个状态提供保护条件,又能提供干净且可维护的代码。如emberjs、ui路由器和react路由器等前端侧路由系统如何实现
保护条件
,以避免在不满足条件时进入特定状态


我想通过使用状态模式来实现一个有限状态机,但我不能对它掉以轻心。简言之,这就像:

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

下面的状态图摘自Martin Fowler的领域特定语言书

他在描述中说:

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

我要强调的是,
转向灯
打开第二个抽屉
可以按任何顺序进行。与A、B和C相同

根据@SQLPolice评论和这本书,我得出以下结论:


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

快速草稿如下所示:


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

使用我为laravel编写的FSM包,一个示例FSM设置

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

这还将触发一个
checkReady()
,它将根据约束标志触发转换或保持当前状态

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

当您查看多个状态时,每个状态都会形成对约束的需求。

当您使用伪状态/处理程序查看单个状态时。
状态机抽象包括:

  • 事件或输入
  • 过渡
  • 行动
  • 像A&&b&&c这样的语句实际上是一个事件或输入。。。用于转换的标签。因此,如果要适应状态机抽象,就需要将其映射到事件。您需要编写代码来进行映射


    若你们的状态机通常是由这样的条件驱动的,那个么你们需要钩住b和c发生变化的事件,或者在定时器上定期检查它们。任何时候它们发生变化,您的代码都会映射到一个事件,并将它们发布到状态机的任何代码中。

    我猜您有一个启动状态?您在用什么画这个呢。。。UML/Flow…?@DavidBarker,两者都不是。我只是需要一些可视化的东西来理解如何实现。好的,但是当你有一个only时,你就想进入一个不同的状态。但是如果你有一个第一个事件会发生什么呢?你怎么知道B或C会紧随其后?哦,现在画得很好是的,你是对的,当变得更复杂时,它会变得非常麻烦。这就是为什么要使用工具来创建这样的状态机——例如
    lex
    flex
    ,等等(用于词法分析)。他们用很多标签创建C代码,并且
    goto
    跳跃…谢谢,但是如果(a&&B&&C),我如何避免编写
    ?原因是,我已经有很多条件不同的if和else。选择状态机的唯一原因是避免这样做。啊,我明白了。这背后是什么——这是学校的作业,还是你想知道什么?这不是作业。我比这类东西老。这是我们面临的一个真正的问题,我们正在努力简化事情。这是很久以前的事了,但我大致记得词汇分析是如何做到这一点的。您可以使用一系列过渡状态来分解“A&B&C”,如下所示:如果您有A,则切换到过渡状态1。现在,如果你有B,那么进入过渡状态2,如果没有,那么进入最终状态1。在过渡状态1中,如果有C,则转到最终状态2。这是一种可能的方法,就像自动化工具一样。创建一个转换事件
    D
    ,其中
    D=(a&&B&&C)