天天看點

設計模式——狀态模式

定義:當一個對象的内在狀态改變時允許改變其行為,這個對象看起來像是改變了其類

簡單的解釋一下狀态模式的定義就是當一個對象的狀态改變了,這個對象的行為也會跟着改變,而看起來就像是這個類改變了一樣

在寫程式的過程中,經常會遇到多種狀态的判斷,首先想到的就是通常的if-else if寫法,但是這種寫法會導緻方法過長,使目前類的責任過大而違背了單一職責的原則,并且後期不好維護,狀态模式主要解決的就是這種狀态的邏輯判斷過于複雜的情況

我們可以把很多狀态的共同相關行為都放入一個抽象類或接口中管理,這樣定義不同的狀态類去繼承基類并實作方法就可以增加修改不同狀态,再通過一個統一的管理類去管理目前狀态的行為,這樣做就可以消除繁瑣的條件分支語句,減少類與類互相間的依賴

總的來說,狀态模式有三種角色,抽象狀态、具體狀态和狀态管理。抽象狀态負責定義很多狀态的共同相關行為,具體狀态角色隻負責處理本狀态的任務和過渡到其他狀态兩個職責,狀态管理負責狀态的過渡,這樣将過渡與狀态分離,提高了程式可擴充性和代碼的可閱讀性

——Context類:可以看作是一個Manager去管理目前狀态以及目前狀态的行為,它持有一個狀态的對象去負責狀态的切換

——IState接口:封裝每個狀态類共同的行為,這些行為的使用(調用)是在Context類中

——具體狀态類:StateA與StateB是兩個不同但有關聯的狀态

例如一個遊戲中人物有三種狀态:站立、走路、跑步

不使用狀态模式的寫法如下:

上面的寫法雖然沒什麼問題,但是有幾點明顯的缺點:

——假設有100個狀态則需要100個if-else if或case,方法過長是不好的

——假設我們隻需要修改在跑步狀态時的Debug輸出,則相當于修改了這個類,違背了單一職責原則也就是開放-封閉原則,不利于對項目的拓展和複用

對上面的寫法使用狀态模式進行改寫:

使用狀态模式改寫後,有幾個明顯的優點:

——去掉了if else-if,使代碼優雅了很多,假設現在需要修改在跑步狀态時的Debug輸出,則隻要改動Run類即可,不需要改動其他的類

——使用多态StateManager playerState = new StateManager(new Idle())這種方式代替了條件判斷,使代碼的擴充性更強,假如現在需要增加一個跳的狀态,則隻需要建立一個Jump類即可

例如一個開關,按下後開啟微弱燈光,再按一下開啟強烈燈光,再按一下關閉燈

繼續閱讀