📜  状态方法Python设计模式

📅  最后修改于: 2022-05-13 01:55:05.176000             🧑  作者: Mango

状态方法Python设计模式

状态方法是一种行为设计模式,它允许对象在其内部状态发生变化时改变其行为。它有助于将状态实现为状态模式接口的派生类。如果我们必须根据状态改变对象的行为,我们可以在对象中拥有一个状态变量,并使用 if-else 条件块来根据状态执行不同的操作。它可以被称为面向对象的状态机。它通过调用模式超类中的方法来实现状态转换。

不使用状态方法的问题

State 方法模式代表有限状态机

有限状态机图

有限状态机图

在任何时候,都可能有一个有限的没有。程序中可以存在的状态。每个州的行为和其他事情都是独一无二的。甚至程序也可以随时从一种状态更改为另一种状态。当且仅当所需的转换在规则中可用时,程序才能从一种状态转到另一种状态。当我们添加大量状态时,它肯定会变得困难。处理代码将变得困难,因为转换逻辑的任何微小变化都可能导致每个方法中状态条件的变化。 =

使用状态方法的解决方案

让我们通过Radio的例子来看看上述问题的解决方案。在这里,收音机有两个状态,分别称为Am StateFM State 。我们可以使用开关在这两种状态之间切换。 State 方法建议我们应该为对象的所有可能状态创建一个新类,并将所有特定于状态的行为提取到这些类中。

原始对象称为上下文,而不是自己实现所有行为,而是存储对表示其当前状态的状态对象之一的引用,并表示该对象的所有与状态相关的工作。

无状态问题法

无状态问题法

"""State class: Base State class"""
class State:
  
    """Base state. This is to share functionality"""
  
    def scan(self):
          
        """Scan the dial to the next station"""
        self.pos += 1
  
        """check for the last station"""
        if self.pos == len(self.stations):
            self.pos = 0
        print("Visiting... Station is {} {}".format(self.stations[self.pos], self.name))
  
"""Separate Class for AM state of the radio"""
class AmState(State):
  
    """constructor for AM state class"""
    def __init__(self, radio):
          
        self.radio = radio
        self.stations = ["1250", "1380", "1510"]
        self.pos = 0
        self.name = "AM"
  
    """method for toggling the state"""
    def toggle_amfm(self):
        print("Switching to FM")
        self.radio.state = self.radio.fmstate
  
"""Separate class for FM state"""
class FmState(State):
  
    """Constriuctor for FM state"""
    def __init__(self, radio):
        self.radio = radio
        self.stations = ["81.3", "89.1", "103.9"]
        self.pos = 0
        self.name = "FM"
  
    """method for toggling the state"""
    def toggle_amfm(self):
        print("Switching to AM")
        self.radio.state = self.radio.amstate
  
"""Dedicated class Radio"""
class Radio:
  
    """A radio. It has a scan button, and an AM / FM toggle switch."""
  
    def __init__(self):
          
        """We have an AM state and an FM state"""
        self.fmstate = FmState(self)
        self.amstate = AmState(self)
        self.state = self.fmstate
  
    """method to toggle the switch"""
    def toggle_amfm(self):
        self.state.toggle_amfm()
  
    """method to scan """
    def scan(self):
        self.state.scan()
  
""" main method """
if __name__ == "__main__":
  
    """ create radio object"""
    radio = Radio()
    actions = [radio.scan] * 3 + [radio.toggle_amfm] + [radio.scan] * 3
    actions *= 2
  
    for action in actions:
        action()

输出

Visiting... Station is 89.1 FM
Visiting... Station is 103.9 FM
Visiting... Station is 81.3 FM
Switching to AM
Visiting... Station is 1380 AM
Visiting... Station is 1510 AM
Visiting... Station is 1250 AM
Visiting... Station is 1380 AM
Visiting... Station is 1510 AM
Visiting... Station is 1250 AM
Switching to FM
Visiting... Station is 89.1 FM
Visiting... Station is 103.9 FM
Visiting... Station is 81.3 FM

UML 图

以下是状态方法的 UML 图

UML 图状态方法

UML 图状态方法

好处

  • Open/Closed 原则:我们可以很容易地引入新的状态而不改变客户端代码现有状态的内容。
  • 单一职责原则:它有助于将特定状态的代码组织到单独的类中,这有助于使代码对其他 depelopers 也可行。
  • 提高凝聚力:它还提高了凝聚力,因为特定于状态的行为被聚合到 ConcreteState 类中,这些类被放置在代码中的一个位置。

缺点

  • 使系统复杂化:如果一个系统只有几个状态,那么使用状态方法不是一个好的选择,因为你最终会添加不必要的代码。
  • 在运行时更改状态:当我们需要在运行时通过在不同的子类中输入来更改状态时,使用 State 方法,这也将被认为是一个缺点,因为我们有一个明确的独立 State 类,其中包含一些逻辑和另一方面,类的数量增加了。
  • 子类依赖:这里每个状态派生类都耦合到它的兄弟,直接或间接地引入了子类之间的依赖。

进一步阅读 – Java中的状态方法