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

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