在状态模式中,谁定义状态转换?

17

我了解到 状态模式(State pattern) 可以用于建模根据不同状态而变化行为的对象,而Context所具有的不同状态则被封装在代表State接口的具体类中。然而,我并不清楚这个模式中状态的转换是如何发生的。是各个State知道并决定了下一个状态,还是由Context决定其下一个状态?

3个回答

16

来自《GOF设计模式》书籍(这段内容出现在实现部分):

1. 谁定义状态转换?状态模式没有指定哪个参与者定义状态转换的标准。如果标准是固定的,那么它们可以完全在上下文中实现。然而,更加灵活和适当的做法是让状态子类自己指定其后继状态以及何时进行转换。这需要在上下文中添加一个接口,让状态对象显式地设置上下文的当前状态。

通过以这种方式分散转换逻辑,可以很容易地通过定义新的状态子类来修改或扩展逻辑。分散化的缺点是一个状态子类将了解至少另一个状态子类,这引入了子类之间的实现依赖关系。


真正的含义是只提到了去中心化状态转换。在此模式之外,仍然需要有人定义状态机作为前提条件。它应该看起来像一个有向图。 - Alex. A

5
也许一个比较具体的例子可以澄清。我希望我理解得正确。
假设一台洗衣机有两种状态(开,关)。按照GoF词汇:
- 上下文 => 洗衣机(WashingMachine) - 状态 => 洗衣机状态(WashingMachineState) - 具体状态 => 开启状态(StateOn),关闭状态(StateOff)
为了进行状态转移,通过状态子类(在我们的例子中是StateOn和StateOff),我们需要有一个方法来更改上下文状态。
class WashingMachine {
   WashingMachineState state;
   ...
   protected void setState(WashingMachineState newState) {
      state = newState;
   }

   someMethod () {
      ...
      state.pushStartButton(this);
      ...
   }
}
abstract class WashingMachineState {
   protected void run();
   protected void pushStartButton(WashingMachine wm);
}
class StateOn extends WashingMachineState {
   ...
   void pushStartButton(WashingMachine wm) {
      wm.setState(new StateOff())
   }
}

class StateOff extends WashingMachineState {
   ...
   void pushStartButton(WashingMachine wm) {
      wm.setState(new StateOn())
   }
}

请记住,有多种实现方法,创造力是有帮助的!


0
我喜欢用单独的类来处理两个状态之间的转换,这是一种我喜欢的状态转换模式。
这样做可以让状态只负责在进入、执行和退出时发生的事情,而单独的代码控制从一个状态到另一个状态的转换。这样可以在只有一个转换时需要发生复杂动作时提供更具体的控制。

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