0
点赞
收藏
分享

微信扫一扫

设计模式:第三章 状态模式

第一章 前言
第二章 观察者模式


第三章 状态模式


1

1. 核心思想

允许一个对象在其内部状态发生改变时改变其行为,使这个对象看上去就像改变了它的类型一样。状态模式是说一个对象在其内部状态发生改变时,其表现的行为和外在属性不一样,这个对象看上去就像改变了它的类型一样。因此,状态模式又称为对象的行为模式。

比如生活中,水有三种不同状态:冰、水、水蒸气。三种不同的状态有着完全不一样的外在特性:冰,质坚硬,无流动性,表面光滑;水,具有流动性;水蒸气:质轻,肉眼看不见,却存在于空气中。这三种状态的特性差距很大,根本不像是同一种东西,但事实却是不管它在什么状态,其内部组成都是一样的,都定水分子( H 2 O H_2O H2O)。

状态模式的核心思想就是一个事物(对象)有多种状态,在不同的状态下所表现出来的行为和属性不一样。

2. UML类图

状态模式UML类图

3. 代码框架

from abc import ABC, abstractmethod

class State(ABC):
    """状态抽象基类
    """

    def __init__(self, name):
        self._name = name

    def getName(self):
        return self._name

    @abstractmethod
    def isMatch(self, stateInfo):
        """状态的属性stateInfo是否在当前的状态范围内

        Args:
            stateInfo (Any): 描述状态的信息
        """
        pass

    @abstractmethod
    def behavior(self, content):
        """定义该状态下Content的行为

        Args:
            content (Content): 与状态相关的上下文
        """
        pass

class Content(ABC):
    """状态模式上下文基类

    Args:
        ABC (abc.ABC): 申明为抽象基类
    """

    def __init__(self) -> None:
        super().__init__()
        self._states = set()
        self._curState = None
        # 状态发生变化依赖的属性,当这一变量由多个变量共同决定时可以将其单独定义成一个类
        self._stateInfo = 0

    def addState(self, state:State):
        self._states.add(state)

    def changeState(self, state:State):
        """Content状态由curState转为state

        Args:
            state (State): 状态类

        Returns:
            _type_: _description_
        """
        if state is None:
            return False
        if self._curState is None:
            print("初始化为", state.getName())
        else:
            print("由", self._curState.getName(), "变为", state.getName())
        self._curState = state

    def getState(self)->State:
        return self._curState

    def setStateInfo(self, stateInfo):
        """Content状态信息改变,状态信息不同值可能对应不同的状态

        Args:
            stateInfo (Any): 状态的描述信息
        """
        self._stateInfo = stateInfo
        for state in self._states:
            if state.isMatch(stateInfo):
                self.changeState(state)
                return

    def _getStateInfo(self):
        return self._stateInfo

    def behavior(self):
        self._curState.behavior(self)


class StateImplA(State):
    def __init__(self, name="stateA"):
        super().__init__(name)

    def isMatch(self, stateInfo):
        return stateInfo > 0

    def behavior(self, Content:Content):
        print(f"Content:{Content} state:{Content.getState().getName()} do some thing...")

class StateImplB(State):
    def __init__(self, name="stateB"):
        super().__init__(name)

    def isMatch(self, stateInfo):
        return stateInfo < 0

    def behavior(self, Content:Content):
        print(f"Content:{Content} state:{Content.getState().getName()} do some thing...")

if __name__ == "__main__":
    content = Content()
    content.addState(StateImplA())
    content.addState(StateImplB())
    content.setStateInfo(-2)
    content.behavior()
    content.setStateInfo(2)
    content.behavior()
    content.setStateInfo(-12)
    content.behavior()

4. 模型说明

4.1 设计要点

  1. 在实现状态模式的时候,实现的场景状态有时候会非常复杂,决定状态变化的因素也非常多,我们可以把决定状态变化的属性单独抽象成一个类StateInfo,这样判断状态属性是否符合当前的状态 isMatch 时就可以传入更多的信息。
  2. 每一种状态应当只有唯一的实例。

4.2 优缺点

  1. 优点:

    • 封装了状态的转换规则,在状态模式中可以将状态的转换代码封装在环境类中,对状态转换代码进行集中管理,而不是分散在一个个业务逻辑中。
    • 将所有与某个状态有关的行为放到一个类中(称为状态类),使开发人员只专注于该状态下的逻辑开发。
    • 允许状态转换逻辑与状态对象合为一体,使用时只需要注入一个不同的状态对象即可使环境对象拥有不同的行为。
  2. 缺点:

    • 会增加系统类和对象的个数。
    • 状态模式的结构与实现都较为复杂,如果使用不当容易导致程序结构和代码的混乱。

5. 应用场景

  1. 一个对象的行为取决于它的状态,并且它在运行时可能经常改变它的状态,从而改变它的行为。
  2. 一个操作中含有庞大的多分支的条件语句,这些分支依赖于该对象的状态,且每一个分支的业务逻辑都非常复杂时,我们可以使用状态模式来拆分不同的分支逻辑,使程序有更好的可读性和可维护性。

[1]程杰.大话数据模式[M].北京:清华大学出版社,2007.
[2]罗伟富.人人都懂设计模式:从生活中领悟设计模式:Python实现[M].北京:电子工业出版社,2019.


  1. 本文为书籍《大话数据模式》和《人人都懂设计模式:从生活中领悟设计模式:Python实现》阅读笔记 ↩︎

举报

相关推荐

0 条评论