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. 状态转换逻辑分散:状态转换的逻辑分散在各个具体状态类中,可能会使得状态转换的整体逻辑不够直观。

适用场景

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

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

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

相关推荐
X56615 小时前
如何在 Laravel 中正确保存嵌套动态表单数据(主服务与子服务)
jvm·数据库·python
FQNmxDG4S5 小时前
Java多线程编程:Thread与Runnable的并发控制
java·开发语言
ZhengEnCi5 小时前
03ab-PyTorch安装教程 📚
python
前端老石人6 小时前
HTML 字符引用完全指南
开发语言·前端·html
matlab_xiaowang6 小时前
Redux 入门:JavaScript 可预测状态管理库
开发语言·javascript·其他·ecmascript
狐狐生风6 小时前
LangChain 向量存储:Chroma、FAISS
人工智能·python·学习·langchain·faiss·agentai
虹科网络安全6 小时前
艾体宝干货|数据复制详解:类型、原理与适用场景
java·开发语言·数据库
狐狐生风6 小时前
LangChain RAG 基础
人工智能·python·学习·langchain·rag·agentai
axng pmje6 小时前
Java语法进阶
java·开发语言·jvm
老前端的功夫7 小时前
【Java从入门到入土】28:Stream API:告别for循环的新时代
java·开发语言·python