2025--简单点--python之状态模式

一个context有可以切换多个state,切换到不同的state可以做不同的handle。

该模式将与状态相关的行为抽取到独立的状态类中, 让原对象将工作委派给这些类的实例, 而不是自行进行处理。

python 复制代码
from __future__ import annotations
from abc import ABC, abstractmethod


class Context:
    """
    The Context defines the interface of interest to clients. It also maintains
    a reference to an instance of a State subclass, which represents the current
    state of the Context.
    """

    _state = None
    """
    A reference to the current state of the Context.
    """

    def __init__(self, state: State) -> None:
        self.transition_to(state)

    def transition_to(self, state: State):
        """
        The Context allows changing the State object at runtime.
        """

        print(f"Context: Transition to {type(state).__name__}")
        self._state = state
        self._state.context = self

    """
    The Context delegates part of its behavior to the current State object.
    """

    def request1(self):
        self._state.handle1()

    def request2(self):
        self._state.handle2()


class State(ABC):
    """
    The base State class declares methods that all Concrete State should
    implement and also provides a backreference to the Context object,
    associated with the State. This backreference can be used by States to
    transition the Context to another State.
    """

    @property
    def context(self) -> Context:
        return self._context

    @context.setter
    def context(self, context: Context) -> None:
        self._context = context

    @abstractmethod
    def handle1(self) -> None:
        pass

    @abstractmethod
    def handle2(self) -> None:
        pass


"""
Concrete States implement various behaviors, associated with a state of the
Context.
"""


class ConcreteStateA(State):
    def handle1(self) -> None:
        print("ConcreteStateA handles request1.")
        print("ConcreteStateA wants to change the state of the context.")
        self.context.transition_to(ConcreteStateB())

    def handle2(self) -> None:
        print("ConcreteStateA handles request2.")


class ConcreteStateB(State):
    def handle1(self) -> None:
        print("ConcreteStateB handles request1.")

    def handle2(self) -> None:
        print("ConcreteStateB handles request2.")
        print("ConcreteStateB wants to change the state of the context.")
        self.context.transition_to(ConcreteStateA())


if __name__ == "__main__":
    # The client code.

    context = Context(ConcreteStateA())
    context.request1()
    context.request2()

output:

Context: Transition to ConcreteStateA

ConcreteStateA handles request1.

ConcreteStateA wants to change the state of the context.

Context: Transition to ConcreteStateB

ConcreteStateB handles request2.

ConcreteStateB wants to change the state of the context.

Context: Transition to ConcreteStateA

状态模式的优点

避免了过多的条件判断:状态模式通过将每个状态的行为封装到对应的类中,避免了在上下文中使用大量的条件判断语句(如if-else或switch-case)来根据状态执行不同的行为。

符合开闭原则:当需要增加新的状态时,只需要添加新的状态类,而不需要修改上下文类或其他状态类。

使状态转换更加明确:每个状态类只关心自己状态下的行为以及如何转换到其他状态,使得状态转换的逻辑更加清晰。

状态模式的缺点

  1. 增加了类的数量:每个状态都需要一个对应的类,可能会导致系统中类的数量增加。
  2. 状态转换逻辑分散:状态转换的逻辑分散在各个具体状态类中,可能会使得状态转换的整体逻辑不够直观。

适用场景

一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为。

一个操作中含有大量的条件语句,且这些条件依赖于对象的状态。

通过状态模式,我们可以将复杂的条件判断转换为状态类之间的转换,使得代码更加清晰和可维护。

相关推荐
csdn_zhangchunfeng5 分钟前
Qt之slots和Q_SLOTS的区别
开发语言·qt
计算机安禾6 分钟前
【C语言程序设计】第35篇:文件的打开、关闭与读写操作
c语言·开发语言·c++·vscode·算法·visual studio code·visual studio
kishu_iOS&AI20 分钟前
Python - 链表浅析
开发语言·python·链表
m0_7336122129 分钟前
C++20概念(Concepts)入门指南
开发语言·c++·算法
大连好光景42 分钟前
conda管理包还是pip管理包
python·conda·pip
m0_730115111 小时前
自动化机器学习(AutoML)库TPOT使用指南
jvm·数据库·python
luffy54591 小时前
Rust语言入门-变量篇
开发语言·后端·rust
FreakStudio1 小时前
MicroPython+PycoClaw,3 分钟搞定 ESP32 跑上 OpenClaw!
python·单片机·嵌入式·电子diy
2301_807367191 小时前
C++中的模板方法模式
开发语言·c++·算法
weixin_537590451 小时前
《C程序语言设计》练习答案(练习1-3)
c语言·开发语言