設計模式之八--狀態模式

狀態模式:當一個對象大的內在狀態改變時允許改變其行爲,這個對象看起來像是改變了其類。

狀態模式主要解決的時當控制一個對象狀態轉換大的條件表達式過於複雜時大的情況,把狀態的判斷邏輯轉移到不同狀態的一系列類當中。

from abc import ABCMeta, abstractmethod


class State:
    @abstractmethod
    def write_program(self, work):
        pass


class ForeNoon(State):

    def write_program(self, work):
        if work.hour > 12:
            work.set_state(Afternoon())
            work.write_program()
        else:
            print("Time is {0}.It is forenoon.".format(work.hour))


class Afternoon(State):

    def write_program(self, work):
        if work.hour > 18:
            work.set_state(Evening())
            work.write_program()
        else:
            print("Time is {0}.It is afternoon.".format(work.hour))


class Evening(State):

    def write_program(self, work):
        if work.hour > 21:
            work.set_state(Sleeping())
            work.write_program()
        else:
            print("Time is {0}.It is evening.".format(work.hour))


class Sleeping(State):

    def write_program(self, work):
        print("Time is {0}.It is time to sleep.".format(work.hour))


class Work:
    def __init__(self):
        self._hour = 0
        self._task_finished = False
        self.current_state = None

    @property
    def hour(self):
        return self._hour

    @hour.setter
    def hour(self, value):
        self._hour = value

    @property
    def task_finished(self):
        return self._task_finished

    @task_finished.setter
    def task_finished(self, value):
        self._task_finished = value

    def set_state(self, state):
        self.current_state = state

    def write_program(self):
        self.current_state.write_program(self)


if __name__ == "__main__":
    project = Work()
    project.set_state(ForeNoon())

    project.hour = 11
    project.write_program()

    project.hour = 13
    project.write_program()

    project.hour = 19
    project.write_program()

    project.hour = 22
    project.write_program()

如果按照面向過程的方式來思考,work類中會進行各種各樣的判斷,最後work類會因爲太長,嵌套太多而閱讀性極差。

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