【设计模式】状态模式

前言

1. 单例模式(Singleton Pattern):保证一个类只有一个实例,并提供一个全局的访问点。

2. 工厂模式(Factory Pattern):定义一个创建对象的接口,但由子类决定要实例化的类是哪一个。

3. 观察者模式(Observer Pattern):定义对象之间的一对多依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都会被自动通知并更新。

4. 装饰器模式(Decorator Pattern):动态地给一个对象添加一些额外的职责,而不会影响到其他对象。

5. 策略模式(Strategy Pattern):定义一系列的算法,将每个算法封装起来,并使它们可以相互替换。

6. 命令模式(Command Pattern):将请求封装成一个对象,从而使用户可以用不同的请求对客户进行参数化。

7. 适配器模式(Adapter Pattern):将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的类能够一起工作。

8. 外观模式(Facade Pattern):为子系统中的一组接口提供一个统一的接口,从而使得子系统更加容易使用。

9. 状态模式(State Pattern):允许一个对象在其内部状态改变时改变其行为。

10. 模板方法模式(Template Method Pattern):定义一个操作中的算法的骨架,而将一些步骤延迟到子类中实现。

这些是Python中常用的设计模式,通过使用这些设计模式可以提高代码的可读性、可维护性和重用性。

状态模式


状态模式是一种行为设计模式,它允许对象在其内部状态发生改变时改变其行为。这种模式通过将状态封装成独立的类,使得对象在不同状态下具有不同的行为,而且可以在运行时切换状态。

组成成分 

  1. 上下文(Context): 上下文类负责维护一个状态对象,可以在运行时切换当前状态。上下文类通常包含客户端感兴趣的方法,并将这些方法委托给当前状态对象执行。在示例中,LightContext 就是上下文类。

  2. 抽象状态(State): 抽象状态是一个接口或抽象类,定义了具体状态类需要实现的方法。这些方法表示在不同状态下对象可能的行为。在示例中,State 是抽象状态类,定义了 handle 方法。

  3. 具体状态(Concrete State): 具体状态是抽象状态的实现,每个具体状态类负责定义在特定状态下对象的行为。在示例中,OnStateOffState 是具体状态类。

  • 上下文类包含一个对抽象状态的引用,通过这个引用调用具体状态的方法。
  • 抽象状态定义了具体状态需要实现的方法,以确保它们在不同状态下有一致的接口。
  • 具体状态实现了抽象状态的方法,并定义了在特定状态下对象的行为。

通过这样的结构,状态模式使得状态的变化对客户端来说是透明的,客户端只需要与上下文类交互,而不必关心对象的具体状态。这样的设计提高了代码的可维护性和扩展性。

具体实例一

from abc import ABC, abstractmethod

# 抽象状态类
class State(ABC):
    @abstractmethod
    def handle(self):
        pass

# 具体状态类
class OnState(State):
    def handle(self):
        return "Light is ON"

class OffState(State):
    def handle(self):
        return "Light is OFF"

# 环境类,维护当前的状态
class LightContext:
    def __init__(self):
        # 初始状态为关闭
        self.state = OffState()

    def set_state(self, state):
        self.state = state

    def perform_operation(self):
        return self.state.handle()

# 客户端代码
if __name__ == "__main__":
    light = LightContext()

    # 当前状态为关闭
    print(light.perform_operation())

    # 切换到开启状态
    light.set_state(OnState())
    print(light.perform_operation())

 State 是抽象状态类,包含一个抽象方法 handle表示状态的行为OnStateOffState 是具体状态类,分别表示灯的开启和关闭状态。

LightContext 是环境类,维护了当前的状态,并有一个方法 perform_operation 来执行当前状态的操作。通过调用 set_state 方法可以在运行时切换状态。

具体实例二

 自动售货机

 自动售货机有空闲、取货、缺货三种不同的状态:当自动售货机处于空闲状态时,它正在等待顾客投币;当自动售货机处于出货状态时,表示正在出货过程中;而当自动售货机处于缺货状态时,是无法配送任何商品的。

class VendingMachine:
    def __init__(self):
        self.state = IdleState()

    def insert_money(self):
        self.state.insert_money(self)

    def dispense(self):
        self.state.dispense(self)


class IdleState:
    def insert_money(self, vending_machine):
        print("Money inserted. Dispensing product...")
        vending_machine.state = DispensingState()

    def dispense(self, vending_machine):
        print("No money has been inserted. Please insert money before dispensing.")


class DispensingState:
    def insert_money(self, vending_machine):
        print("Cannot insert money while dispensing. Please wait for dispensing to complete.")

    def dispense(self, vending_machine):
        print("Product dispensed. Enjoy!")
        vending_machine.state = IdleState()


class OutOfStockState:
    def insert_money(self, vending_machine):
        print("Vending machine is out of stock. Cannot dispense product.")

    def dispense(self, vending_machine):
        print("Vending machine is out of stock. Cannot dispense product.")

 VendingMachine类维护自动售货机的当前状态并提供插入货币和分发产品的方法。 三个状态子类(IdleStateDispensingState和 OutOfStockState)在每个可能的状态下实现自动售货机的行为。 当客户与自动售货机交互时,VendingMachine 类会根据客户的操作和机器的当前状态更改其状态。 例如,如果自动售货机处于空闲状态并且客户投入资金,则VendingMachine类将转换为分发状态并开始分发产品。

应用场景 

  1. 对象状态转换: 当一个对象的行为取决于它的状态,并且它需要在运行时根据状态改变其行为时,使用状态模式是很合适的。这有助于消除大量的条件语句,并使代码更清晰。

  2. 行为随状态改变: 如果一个对象有多个状态,且每个状态都对应不同的行为,而且这些状态之间可以相互转换,那么状态模式是一个很好的选择。

  3. 条件语句过多: 当一个对象有很多状态,并且对象的行为随状态的改变而改变时,使用状态模式可以避免大量的条件语句,提高代码的可读性和可维护性。

  4. 事件驱动系统: 在事件驱动的系统中,对象的行为通常与特定事件相关。状态模式可以用来管理对象在不同事件下的行为。

  5. 工作流和状态机: 在工作流和状态机的设计中,状态模式常常用于描述对象在状态转换时的行为。

  6. 游戏开发: 游戏中的角色状态经常需要根据游戏进程进行切换,状态模式能够有效地管理这些状态转换。

参考链接:

Python状态设计模式快速入门 - 知乎

你可能感兴趣的:(python,设计模式,状态模式)