【问题标题】:State pattern: Which class should I trust to update the state? [closed]状态模式:我应该信任哪个类来更新状态? [关闭]
【发布时间】:2011-08-02 18:08:33
【问题描述】:

我正在通过阅读Head First Design Patterns来学习设计模式,并且我刚刚完成了状态模式这一章。但是,我不明白一件事:

在书中,有状态的类称为Context,而实际的状态实现State接口。当给书一个请求时,使用这里的方法来改变状态:

  1. 上下文接收请求;
  2. Context 调用其拥有的 State 上的 handle() 方法,将请求交给 State;
  3. State 处理请求,如果需要更改,则在 Context 中设置 State。为此,States 将 Context 作为一个字段。

但是,在我看来,这在两个类之间给出了某种“递归”耦合,并且不直观。如果我还没有阅读他们的解决方案,我更喜欢以下设计:

  1. 上下文接收请求;
  2. Context 调用其拥有的 State 上的 handle() 方法,将请求交给 State;
  3. State处理请求,并返回一个State;是否是另一个州取决于请求的处理方式。
  4. 上下文将自己的状态设置为返回的状态。

我能想到的利弊:

  1. 如果我们将所有可能变化的内容放入 State 类、Context 和 State 中并变得更加解耦,因为它们不需要窥视彼此的字段;
  2. State 类可能会变得更大;
  3. 状态可能不容易在不同的上下文中重用。但是,我们可以将States 实现为实现State 接口的抽象类,并具有由抽象States 子类化的Contexts 使用的具体States。

是否有任何具体原因应该支持第一个(Head First Design Patterns 使用),或者第二个选择也有效并在实践中使用,或者它有一些我没有看到的严重缺陷?

感谢您的所有投入以及您花时间阅读和回复!

【问题讨论】:

    标签: design-patterns decoupling state-pattern


    【解决方案1】:

    您提到的方法的问题是,在您描述的场景中,引用 State 对象的任何其他对象都无法获得更新。正如您所描述的,State 可以返回另一个具有更新 State 的 State,并且 Context 可以用更新的 State 替换其对 State 的引用,但是任何其他引用 State 的对象现在都将有一个悬空引用,而不是由上下文引用。

    【讨论】:

    • 我明白了,这是一个很好的答案。但在这种情况下,原来的人会怎么做?它会持有一个 ArrayList 并改变所有上下文的状态吗?或者也许我们可以使用两级设计,其中一个为所有上下文保存状态,因此我们不必通知所有上下文?谢谢!
    • @ZiyaoWei:不,每个State对象都负责更新自己的内部状态信息;当状态修改自身时,引用该状态的所有内容都会看到更新。这就是将状态信息封装在 State 对象中的原因;每个 State 对象负责自己的信息,并且可以在其值发生变化时通知任何相关的侦听器(即 Context)。
    【解决方案2】:

    还有第三种方式,不是将上下文作为状态的成员,而是将状态实现为单例模式,并将上下文作为参数传递给状态的事件成员函数。这与享元模式中使用的技术相同。这样,就可以使用一组上下文,但每个状态只能使用一个实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-22
      • 1970-01-01
      相关资源
      最近更新 更多