Android 設計模式 - 狀態模式
1. 定義
允許一個物件在其內部狀態改變時改變它的行為,物件看起來似乎修改了它的類。它是一種物件行為型模式。
2. 作用
狀態模式把所研究的物件的行為包裝在不同的狀態物件裡,每一個狀態物件都屬於一個抽象狀態類的一個子類。狀態模式的意圖是讓一個物件在其內部狀態改變的時候,其行為也隨之改變。
3. 角色
- 環境(Context)角色,也叫上下文:定義客戶端所感興趣的介面,並且保留一個具體狀態類的例項。這個具體狀態類的例項給出此環境物件的現有狀態。
- 抽象狀態(State)角色:定義一個介面,用以封裝環境(Context)物件的一個特定的狀態所對應的行為。
- 具體狀態(ConcreteState)角色:每一個具體狀態類都實現了環境(Context)的一個狀態所對應的行為。
4. 實現
舉個例子,路口的交通訊號燈就有不同的狀態,紅燈停、綠燈行、黃燈暫停。所以,我們就用狀態模式來模擬這個過程。

類圖
- 定義抽象狀態,即紅綠燈在亮起時,表現的行為。
public interface ILightState { /** * 行為表示 */ void behave(); }
- 定義具體狀態,分別是紅燈、綠燈和黃燈的實現。
public class RedLight implements ILightState { @Override public void behave() { System.out.println("紅燈停"); } } public class GreenLight implements ILightState { @Override public void behave() { System.out.println("綠燈行"); } } public class YellowLight implements ILightState { @Override public void behave() { System.out.println("黃燈亮了等一等"); } }
- 定義環境角色,交管系統負責訊號燈,按照一定的規則進行控制。
public class TrafficSystem { private ILightState redLight = new RedLight(); private ILightState greenLight = new GreenLight(); private ILightState yellowLight = new YellowLight(); public void work() { double random = Math.random(); if (random > 0.33) { redLight.behave(); } else if (random > 0.67) { greenLight.behave(); } else { yellowLight.behave(); } } }
- 客戶角色,訊號燈投入使用,並正常執行。
public static void main(String[] args) { TrafficSystem trafficSystem = new TrafficSystem(); trafficSystem.work(); }
5. 優缺點
1. 優點:
封裝了轉換規則,並列舉可能的狀態,它將所有與某個狀態有關的行為放到一個類中,並且可以方便地增加新的狀態,只需要改變物件狀態即可改變物件的行為,還可以讓多個環境物件共享一個狀態物件,從而減少系統中物件的個數。
2. 缺點:
使用狀態模式會增加系統類和物件的個數,且狀態模式的結構與實現都較為複雜,如果使用不當將導致程式結構和程式碼的混亂,對於可以切換狀態的狀態模式不滿足「開閉原則」的要求。
3. 使用場景:
物件的行為依賴於它的狀態(屬性),並且可以根據它的狀態改變而改變它的相關行為;程式碼中包含大量與物件狀態有關的條件語句,這些條件語句的出現,會導致程式碼的可維護性和靈活性變差,不能方便地增加和刪除狀態,使客戶類與類庫之間的耦合增強。
【附錄】

資料圖