Python狀態設計模式

定義狀態設計模式

行爲模式關注的是對象的響應性。它們通過對象之間的交互以實現更強大的功能。狀態設計模式是一種行爲設計模式,有時也被稱爲狀態模式對象。在此模式中,一個對象可以基於其內部狀態封裝多個行爲。狀態模式也可以看作是在運行時改變對象行爲的一種方式。

狀態設計模式允許對象在其內部狀態變化時改變其行爲。這看起來就像對象本身已經改變了它的類一樣。狀態設計模式常用於開發有限狀態機,並幫助協調狀態處理操作。

理解狀態設計模式

狀態設計模式的三個主要參與者:

1、State:這被認爲是封裝對象行爲的接口。這個行爲與對象的狀態相關聯。

2、ConcreteState:這是實現State接口的子類。ConcreteState實現對象的特定狀態相關聯的實際行爲

3、Context:這定義了客戶感興趣的接口。Context還維護一個ConcreteState子類的實例,該子類在內部定義了對象的特定狀態的實現

下面我們來考察帶有上述3個參與者的狀態設計模式的結構代碼實現:

from abc import ABCMeta, abstractmethod


class State(metaclass=ABCMeta):
    @abstractmethod
    def handle(self):
        pass


class ConcreteStateA(State):
    def handle(self):
        print("ConcreteStateA")


class ConcreteStateB(State):
    def handle(self):
        print("ConcreteStateB")


class Context(State):
    def __init__(self):
        self.state = None

    def get_state(self):
        return self.state

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

    def handle(self):
        self.state.handle()


context = Context()
stateA = ConcreteStateA()
stateB = ConcreteStateB()

context.set_state(stateA)
context.handle()

狀態設計模式的簡單示例

下面的代碼實現電視遙控器的開關按鈕:

from abc import abstractmethod, ABCMeta


class State(metaclass=ABCMeta):
    @abstractmethod
    def do_this(self):
        pass


class StartState(State):
    def do_this(self):
        print("TV on")


class StopState(State):
    def do_this(self):
        print("TV off")


class TVContext(State):
    def __init__(self):
        self.state = None

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

    def get_state(self):
        return self.state

    def do_this(self):
        self.state.do_this()


context = TVContext()
context.get_state()

start = StartState()
stop = StopState()

context.set_state(stop)
context.do_this()

狀態設計模式簡單示例2

例如一個計算機系統,它可以有多個狀態;如開機、關機、掛起或休眠。現在想利用狀態設計模式來表述這些狀態;

首先從ComputerState接口開始:

1、state應定義兩個屬性,它們是name和allowed。屬性name表示對象的狀態,而屬性allowed是定義允許進入狀態的對象的列表

2、state必須定義一個switch()方法,由它來實際改變對象的狀態

class ComputerState(object):
    name = 'state'
    allowed = []

    def switch(self, state):
        if state.name in self.allowed:
            print('Current:', self, '=>switched to new state', state.name)
        else:
            print('Current:', self, '=>switched to', state.name, 'not possible')

    def __str__(self):
        return self.name

下面實現State接口的ConcreteState,我們定義了四個狀態

1、 On:這將打開計算機。這時候允許的狀態是Off、Suspend和Hibernate。

2、Off:這將關閉計算機。這時候允許的狀態只有On

3、Hibernate:該狀態將計算機置於休眠模式。當計算機處於這種狀態時,只能執行打開操作

4、Suspend:該狀態將使計算機掛起,一旦計算機掛起,就可以執行打開操作

class Off(ComputerState):
    name = 'off'
    allowed = ['on']


class On(ComputerState):
    name = 'on'
    allowed = ['off', 'suspend', 'hibernate']


class Suspend(ComputerState):
    name = 'suspend'
    allowed = ['on']


class Hibernate(ComputerState):
    name = 'hibernate'
    allowed = ['on']

現在考慮context類,上下文需要做兩個主要的事情:

1、__init__():該方法定義了計算機的基本狀態。

2、change():該方法將更改對象的狀態,但是行爲的實際更改是由ConcreteState類實現的

class Computer(object):
    def __init__(self, model='HP'):
        self.model = model
        self.state = Off()
        
    def change(self, state):
        self.state.switch(state)

以下是客戶端的代碼:

if __name__ == "__main__":
    comp = Computer()
    comp.change(On)
    comp.change(Off)

    comp.change(On)
    comp.change(Suspend)
    comp.change(Hibernate)
    comp.change(On)
    comp.change(Off)

 

狀態模式的優缺點

優點:

1、在狀態設計模式中,對象的行爲是其狀態的函數結果,並且行爲在運動時根據狀態而改變。這消除了if/else或switch/case條件邏輯的依賴。

2、使用狀態模式,實現多態行爲的好處顯而易見的,並且更易於添加狀態來支持額外的行爲

3、狀態設計還提高了聚合性,因爲特定於狀態的行爲被聚合到ConcreteState類中,並且放置在代碼中的同一個地方

4、使用狀態設計模式,通過只添加一個ConcreteState類來添加行爲是非常容易的。因此,狀態模式不僅改善了擴展應用程序行爲時的靈活性,而且全面提高了代碼的可維護性。

缺點:

1、類爆炸:由於每個狀態都需要在ConcreteState的幫助下定義,因此我們可能導致創建了太多功能比較單一的類。我們不妨考慮有限狀態機的情況——如果有許多狀態,但是每個狀態與另一個狀態沒有太大的不同,我們仍然需要將它們寫成單獨的ConcreteState類。這即增加了代碼量,又使得狀態機構更加難以審查。

2、隨着每個新行爲的引入,Context類都需要進行相應的更新處理每個行爲。這使得上下文行爲更容易受到每個新的行爲的影響。

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