前言
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):
@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
,表示状态的行为。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
类将转换为分发状态并开始分发产品。
应用场景
-
对象状态转换: 当一个对象的行为取决于它的状态,并且它需要在运行时根据状态改变其行为时,使用状态模式是很合适的。这有助于消除大量的条件语句,并使代码更清晰。
-
行为随状态改变: 如果一个对象有多个状态,且每个状态都对应不同的行为,而且这些状态之间可以相互转换,那么状态模式是一个很好的选择。
-
条件语句过多: 当一个对象有很多状态,并且对象的行为随状态的改变而改变时,使用状态模式可以避免大量的条件语句,提高代码的可读性和可维护性。
-
事件驱动系统: 在事件驱动的系统中,对象的行为通常与特定事件相关。状态模式可以用来管理对象在不同事件下的行为。
-
工作流和状态机: 在工作流和状态机的设计中,状态模式常常用于描述对象在状态转换时的行为。
-
游戏开发: 游戏中的角色状态经常需要根据游戏进程进行切换,状态模式能够有效地管理这些状态转换。
参考链接: