Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 状态模式:我应该信任哪个类来更新状态?_Design Patterns_Decoupling_State Pattern - Fatal编程技术网

Design patterns 状态模式:我应该信任哪个类来更新状态?

Design patterns 状态模式:我应该信任哪个类来更新状态?,design-patterns,decoupling,state-pattern,Design Patterns,Decoupling,State Pattern,我正在通过阅读Head-First设计模式来学习设计模式,我刚刚完成了关于状态模式的章节。然而,有一件事我不明白: 在本书中,具有状态的类称为上下文,而实际状态实现状态接口。当发出请求时,请使用此处的方法更改状态: 上下文接收请求 上下文在其所处的状态上调用handle()方法,将请求交给状态 状态处理请求,如果请求发生更改,则在上下文中设置状态。为此,各州将上下文作为一个字段。 然而,在我看来,这似乎在两个类之间提供了某种“递归”耦合,并且是不直观的。如果我没有阅读过他们的解决方案,我更喜欢以

我正在通过阅读Head-First设计模式来学习设计模式,我刚刚完成了关于状态模式的章节。然而,有一件事我不明白:

在本书中,具有状态的类称为上下文,而实际状态实现状态接口。当发出请求时,请使用此处的方法更改状态:

  • 上下文接收请求
  • 上下文在其所处的状态上调用handle()方法,将请求交给状态
  • 状态处理请求,如果请求发生更改,则在上下文中设置状态。为此,各州将上下文作为一个字段。
  • 然而,在我看来,这似乎在两个类之间提供了某种“递归”耦合,并且是不直观的。如果我没有阅读过他们的解决方案,我更喜欢以下设计:

  • 上下文接收请求
  • 上下文在其所处的状态上调用handle()方法,将请求交给状态
  • 状态处理请求,并返回状态;是否为另一种状态取决于请求的处理方式。
  • 上下文将自己的状态设置为返回的状态。
  • 我能想到的优点和缺点是:

  • 如果我们将所有可能变化的内容放入状态类、上下文和状态中,并且变得更加解耦,因为它们不需要窥视彼此的字段
  • 国家阶级可能会变得更大
  • 状态可能不容易在不同的上下文中重用。但是,我们可以将状态实现为实现状态接口的抽象类,并具有具体的状态,这些状态由对抽象状态进行子类化的上下文使用
  • 有没有什么具体的原因让第一个(由Head first设计模式使用)更受欢迎,或者第二个选择也是有效的并在实践中使用,或者它有一些我没有看到的严重缺陷


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

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

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

    我明白了,这是一个很好的答案。但在这种情况下,最初的一个会做什么呢?它会保存(比如)一个ArrayList并更改所有上下文的状态吗?或者我们可以使用两级设计,其中一级保存所有上下文的状态,这样我们就不必通知所有上下文了?谢谢@ZiyaoWei:不,每个状态对象负责更新自己的内部状态信息;当状态修改自身时,引用该状态的所有内容都会看到更新。这就是在state对象中封装状态信息的原因;每个状态对象负责自己的信息,并且可以在其值更改时通知任何相关侦听器(即上下文)。