前言
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中常用的设计模式,通过使用这些设计模式可以提高代码的可读性、可维护性和重用性。
状态模式
状态模式是一种行为设计模式,它允许对象在其内部状态发生改变时改变其行为。这种模式通过将状态封装成独立的类,使得对象在不同状态下具有不同的行为,而且可以在运行时切换状态。
组成成分
-
上下文(Context): 上下文类负责维护一个状态对象,可以在运行时切换当前状态。上下文类通常包含客户端感兴趣的方法,并将这些方法委托给当前状态对象执行。在示例中,
LightContext就是上下文类。 -
抽象状态(State): 抽象状态是一个接口或抽象类,定义了具体状态类需要实现的方法。这些方法表示在不同状态下对象可能的行为。在示例中,
State是抽象状态类,定义了handle方法。 -
具体状态(Concrete State): 具体状态是抽象状态的实现,每个具体状态类负责定义在特定状态下对象的行为。在示例中,
OnState和OffState是具体状态类。
- 上下文类包含一个对抽象状态的引用,通过这个引用调用具体状态的方法。
- 抽象状态定义了具体状态需要实现的方法,以确保它们在不同状态下有一致的接口。
- 具体状态实现了抽象状态的方法,并定义了在特定状态下对象的行为。
通过这样的结构,状态模式使得状态的变化对客户端来说是透明的,客户端只需要与上下文类交互,而不必关心对象的具体状态。这样的设计提高了代码的可维护性和扩展性。
具体实例一
from abc import ABC, abstractmethod# 抽象状态类
class State(ABC):@abstractmethoddef 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 = statedef 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,表示状态的行为。OnState 和 OffState 是具体状态类,分别表示灯的开启和关闭状态。
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类维护自动售货机的当前状态并提供插入货币和分发产品的方法。 三个状态子类(IdleState、DispensingState和 OutOfStockState)在每个可能的状态下实现自动售货机的行为。 当客户与自动售货机交互时,VendingMachine 类会根据客户的操作和机器的当前状态更改其状态。 例如,如果自动售货机处于空闲状态并且客户投入资金,则VendingMachine类将转换为分发状态并开始分发产品。
应用场景
-
对象状态转换: 当一个对象的行为取决于它的状态,并且它需要在运行时根据状态改变其行为时,使用状态模式是很合适的。这有助于消除大量的条件语句,并使代码更清晰。
-
行为随状态改变: 如果一个对象有多个状态,且每个状态都对应不同的行为,而且这些状态之间可以相互转换,那么状态模式是一个很好的选择。
-
条件语句过多: 当一个对象有很多状态,并且对象的行为随状态的改变而改变时,使用状态模式可以避免大量的条件语句,提高代码的可读性和可维护性。
-
事件驱动系统: 在事件驱动的系统中,对象的行为通常与特定事件相关。状态模式可以用来管理对象在不同事件下的行为。
-
工作流和状态机: 在工作流和状态机的设计中,状态模式常常用于描述对象在状态转换时的行为。
-
游戏开发: 游戏中的角色状态经常需要根据游戏进程进行切换,状态模式能够有效地管理这些状态转换。
参考链接:
Python状态设计模式快速入门 - 知乎