状态模式与记忆功能

4
我曾在一个普通的状态机中使用了状态模式(State Pattern)。我想实现从[A -> B], [B -> C] 和 [A -> C] 的转换。现在我们的领域规则发生了变化,我需要增加一条新规则,即只有在从未经过B的情况下,才能够从[C -> A]转换到A。这就要求状态有记忆性(states with memory)。有两种可能的解决方案:
  1. 创建一个新的状态CB指代B之后的C,并且遵循以下规则:[A -> B],[B -> CB],[A -> C],[C -> A]
  2. 利用上下文(Context)保存的先前状态列表(我们称之为StateHistoric),以及进行状态转换的日期(状态历史也是我们客户的领域需求)。然后按照以下规则进行状态转换:[A -> B],[B -> C],[A -> C],[C -> A,如果B不在Context.StateHistoric中]
哪种方法更适合状态模式中的记忆功能(或者其他这两种方式之外的替代方案)?
谢谢。

如果条件变得更加复杂,例如现在我只有在从C到A的时候没有去过B两次才能这样做,那么如果我选择解决方案1,所需状态的数量将会增加,因此它不是一个灵活的解决方案,解决方案2会更容易适应,因为我只需要计算历史记录中B的数量。因此出于灵活性的考虑,我更倾向于选择解决方案2。 - Miguel Marques
5个回答

3

采用第二种解决方案。它更容易理解,也更容易扩展。

不要因为设计模式听起来与你喜欢的方式相似而坚持遵循它。


2

如果它有内存,那么它就不是真正的状态机。如果您想保持这个身份,则选项1是正确的选择。


1

带有记忆的状态机确实存在,它们被称为下推自动机... 其思想是拥有一个堆栈,您可以在到达状态时读取它,并在离开状态时写入它。 关于状态设计模式,我想它可以作为上下文中的备忘录来实现。


0

选项#2可行。你的历史记录列表有多大?如果搜索列表变得很长,那么我会选择选项#3:在你的上下文中添加一个名为visitedStateB的布尔标志。在初始化时将此标志设置为false。当一个状态转换带你进入状态B时,将该标志设置为true。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接