設計模式——狀態模式

定義

狀態模式,又稱狀態對象模式(Pattern of Objects for States),狀態模式是對象的行為模式。

狀態模式允許一個對象在其內部狀態改變的時候改變其行為。這個對象看上去就像是改變了它的類一樣。

使用場景

  • 一個對象的行為取決與它的狀態,而且它必須在運行時根據狀態改邊他的行為
  • 代碼中包含大量與對象有關的條件語句,比如,在一個方法中含有多重的判斷語句(if-else或者switch-case),并且這些分支依賴這個對象的狀態

結構與UML圖

UML.png

角色介紹:

  • Context:環境類,定義用戶感興趣的接口嗎,維護一個State子類的實例,這個實例定義了當前的狀態。
  • State:抽象狀態類或者接口,定義一個或者一組接口,表示某種狀態下的行為
  • ConcreteState:具體狀態類,每一個具體的狀態類實現抽象State中定義的接口,從而達到不同狀態下的不同行為

簡單事例

這里以wifi連接來簡單的演示一下:

環境類:

public class Context {
    //維護一個State子類的實例,這個實例定義了當前的狀態
    private State state;

    public void setState(State state) {
        this.state = state;
    }
    /**
     * 用戶感興趣的接口方法
     */
    public void powerOn(){
        state.connect();
    }
    public void powerOff() {
        state.off();
    }
}

抽象狀態類:

public interface State {
    /**
     * 狀態對應的處理
     */
    public void connect();
    public void off();
}

具體狀態類:

//關閉狀態,觸發沒有任何操作
public class ConcreteStateA implements State {

    @Override
    public void connect() {

    }

    @Override
    public void off() {

    }

}


//開啟狀態
public class ConcreteStateB implements State {

    @Override
    public void connect() {
        System.out.println("連接成功");
    }

    @Override
    public void off() {
        System.out.println("斷開成功");
    }

}

客戶端類:

public class Client {

    public static void main(String[] args) {
         //創建狀態
        State state=new ConcreteStateOpen();
        //創建環境
        Context context=new Context();
        //將狀態設置到環境中
        context.setState(state);
        //具體請求
        context.powerOn();
        context.powerOff();
    }
}

如果你覺得每次要重新手動創建一個狀態麻煩,我們可以改一下環境類:

public class Context {
    //維護一個State子類的實例,這個實例定義了當前的狀態
    private State state;

    public void setState(State state) {
        this.state = state;
    }
    /**
     * 用戶感興趣的接口方法
     */
    public void powerOn(){
        setState(new ConcreteStateOpen());
        System.out.println("開啟啦");
    }
    public void powerOff() {
        setState(new ConcreteStateClose());
        System.out.println("關閉啦");
    }
    public void C() {
        state.connect();
    }
    
    public void O() {
        state.off();
    }
}

這樣在客戶端類里面更改狀態更加方便了:

public class Client {

    public static void main(String[] args) {
        Context context=new Context();
        //設置開啟狀態
        context.powerOn();
        //開啟
        context.C();
        //關閉
        context.O();
        //設置關閉狀態
        context.powerOff();
        context.C();
    }
}

優點

  • 封裝轉換過程,也就是轉換規則
  • 枚舉可能的狀態,因此,需要事先確定狀態種類。
  • 將所有與某個狀態有關的行為放到一個類中,并且可以方便地增加新的狀態,只需要改變對象狀態即可改變對象的行為。
  • 允許狀態轉換邏輯與狀態對象合成一體,而不是某一個巨大的條件語句塊。
  • 可以讓多個環境對象共享一個狀態對象,從而減少系統中對象的個數。

缺點

狀態模式的使用必然會增加系統類和對象的個數

總結

狀態模式的關鍵之處在于不同的狀態下對于同一個行為有不同的響應,其實就是使用多態實現的一個具體的if-else語句。但是減少了代碼的邏輯耦合。在Android中,狀態模式最常用的案例就是用戶登陸系統

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容