python设计模式20-状态模式

1. 状态模式(State)介绍

UML类图

在这里插入图片描述

应用场景

行为状态改变的场景。这点在各种控制器中非常常见,同时,逻辑结构为状态转移图的场景中都非常适用。

优点

  • 状态模式的优点是结构清晰,相比于if…else…简约了不少;
  • 封装性好,外部调用不必知道内部实现细节。

缺点

  • 在状态比较多时,子类也会非常多,不便于管理。

2. 示例

  • 电梯在我们周边随处可见,电梯的控制逻辑中心是由电梯控制器实现的。电梯的控制逻辑,即使简单点设计,把状态分成开门状态,停止状态和运行状态,操作分成开门、关门、运行、停止,那流程也是很复杂的。首先,开门状态不能开门、运行、停止;停止状态不能关门,停止;运行状态不能开门、关门、运行。要用一个一个if…else…实现,首先代码混乱,不易维护;二是不易扩展。
  • 那该如何实现?每个操作仅仅是一个操作,状态切换与操作是分离的,这也造成后来操作和状态“相互配合”的“手忙脚乱”。如果把状态抽象成一个类,每个状态为一个子类,每个状态实现什么操作,不实现什么操作,仅仅在这个类中具体实现就可以了。
"""State Pattern with Python Code
"""

from abc import abstractmethod, ABCMeta


# 抽象的状态类
class LiftState(metaclass=ABCMeta):
    @abstractmethod
    def open(self):
        pass

    @abstractmethod
    def close(self):
        pass

    @abstractmethod
    def run(self):
        pass   
 
    @abstractmethod
    def stop(self):
        pass


class OpenState(LiftState):
    def open(self):
        print("OPEN:The door is opened...")
        return self

    def close(self):
        print("OPEN:The door start to close...")
        print("OPEN:The door is closed")
        return StopState()

    def run(self):
        print("OPEN:Run Forbidden.")
        return self
    
    def stop(self):
        print("OPEN:Stop Forbidden.")
        return self


class RunState(LiftState):
    def open(self):
        print("RUN:Open Forbidden.")
        return self

    def close(self):
        print("RUN:Close Forbidden.")
        return self

    def run(self):
        print("RUN:The lift is running...")
        return self

    def stop(self):
        print("RUN:The lift start to stop...")
        print("RUN:The lift stopped...")
        return StopState()


class StopState(LiftState):
    def open(self):
        print("STOP:The door is opening...")
        print("STOP:The door is opened...")
        return OpenState()

    def close(self):
        print("STOP:Close Forbidden")
        return self
    
    def run(self):
        print("STOP:The lift start to run...")
        return RunState()

    def stop(self):
        print("STOP:The lift is stopped.")
        return self


class Context(LiftState):
    def getState(self):
        return self._state

    def setState(self, state):
        self._state = state
    
    def open(self):
        self.setState(self._state.open())
    
    def close(self):
        self.setState(self._state.close())
    
    def run(self):
        self.setState(self._state.run())

    def stop(self):
        self.setState(self._state.stop())
    

# 电梯先在STOP状态,然后开门,开门时运行Run,被禁止,然后,关门、运行、停止。
class Client(object):
    def main(self):
        ctx = Context()
        ctx.setState(StopState())
        ctx.open()
        ctx.run()
        ctx.close()
        ctx.run()
        ctx.stop() 


if __name__ == "__main__":
    Client().main()

输出:

# ./State.py
STOP:The door is opening...
STOP:The door is opened...
OPEN:Run Forbidden.
OPEN:The door start to close...
OPEN:The door is closed
STOP:The lift start to run...
RUN:The lift start to stop...
RUN:The lift stopped...

参考:
https://www.cnblogs.com/jokezl/p/10227328.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章