Android中的設計模式之狀態模式

參考

  • 《設計模式:可複用面向對象軟件的基礎 》5.8 State 狀態 對象行爲型模式
  • 《Android源碼設計模式解析與實戰》第7章 隨遇而安--狀態模式

意圖

容許一個對象在其內部狀態改變時改變它的行爲。對象看起來彷佛修改了它的類。java

別名

狀態對象(Objects for States)設計模式

適用場景

  • 一個對象的行爲取決於它的狀態,而且它必須在運行時刻根據狀態改變它的行爲。
  • 一個操做中含有龐大的多分支的條件語句,且這些操做分支包含這一相同的狀態。這個狀態一般用一個或多個枚舉常量表示。

狀態模式將每個條件分支放入到一個獨立的類中,這使得你能夠根據對象自身的狀況將對象狀態做爲一個對象,這一對象能夠不依賴於其它對象而獨立變化,這樣能夠經過多態來去除多的,重複的if-else等分支語句。ide

結構

結構

  • Context 環境類,定義客戶須要的接口,維護一個State子類的實例,這個實例定義了當前環境的狀態。
  • State 抽象狀態類或者狀態接口,定義一個或者一組接口,即是該狀態下的行爲。
  • ConcreteStateA,ConcreteStateB 具體狀態類,每個具體的狀態類實現抽象State中定義的接口,從而達到不一樣狀態下的不一樣行爲。

優勢

State模式將全部與一個特定的狀態相關的行爲都放入一個狀態對象中,它提供了一個更好的方法來組織與特定狀態相關的代碼,將繁瑣的狀態判斷轉換爲結構清晰的狀態類族,再避免代碼膨脹的同時也保證了可擴展性與可維護性。this

缺點

增長了系統類和對象的個數。spa

應用例子1 電視遙控器

描述

電視的狀態分爲開機和關機狀態,開機能夠進行頻道切換,調整音量等操做,可是這時重複開機鍵是無效的;關機狀態下,頻道切換,調整音量,關機都是無效的操做,只有按開機鍵會生效。設計

結構

結構

代碼實現

/**
 *  電視不一樣狀態下的相同抽象行爲接口
 * @author newtrekWang
 * @email  wangjiaxing20160101@gmail.com
 * @time   2018/8/15  23:30
 */
public interface TvState {
    /**
     * 音量調高
     */
    void turnOn();

    /**
     * 音量調低
     */
    void turnOff();

    /**
     * 下一個頻道
     */
    void nextChannel();

    /**
     * 上一個頻道
     */
    void preChannel();
}

/**
 *  關機狀態下的行爲實現
 * @author newtrekWang
 * @email  wangjiaxing20160101@gmail.com
 * @time   2018/8/15  23:22
 */
public class PowerOffState implements TvState {
    @Override
    public void turnOn() {
       // 沒有實現即失靈
    }

    @Override
    public void turnOff() {
        // 沒有實現即失靈
    }

    @Override
    public void nextChannel() {
        // 沒有實現即失靈
    }

    @Override
    public void preChannel() {
        // 沒有實現即失靈
    }
}

/**
 *  開機狀態下的行爲實現
 * @author newtrekWang
 * @email  wangjiaxing20160101@gmail.com
 * @time   2018/8/15  23:22
 */
public class PowerOnState implements TvState {
    @Override
    public void turnOn() {
        System.out.println("音量調高");
    }

    @Override
    public void turnOff() {
        System.out.println("音量調低");
    }

    @Override
    public void nextChannel() {
        System.out.println("切換到了下一個頻道");
    }

    @Override
    public void preChannel() {
        System.out.println("切換到了上一個頻道");
    }
}

/**
 *  電視機遙控器類
 * @author newtrekWang
 * @email  wangjiaxing20160101@gmail.com
 * @time   2018/8/15  23:29
 */
public class TvController {
    private TvState state;

    public void powerOn(){
        this.state = new PowerOnState();
        System.out.println("已開機");
    }

    public void powerOff(){
        this.state = new PowerOffState();
        System.out.println("已關機");
    }

    public void turnOn() {
        state.turnOn();
    }

    public void turnOff() {
        state.turnOff();
    }


    public void nextChannel() {
        state.nextChannel();
    }

    public void preChannel() {
        state.preChannel();
    }

}

應用例子2 Android源碼中的WifiDriverState

後更code

應用例子3 App中的不一樣登錄狀態下的執行行爲

好比應用在已登陸狀態,點擊評論,會正常彈出評論框,而未登陸狀態下,則是要跳轉到登陸界面登陸後,再正常評論。對象

因此已登陸和未登陸狀態下的評論行爲是不一樣的,這個就能夠用狀態模式設計。接口

相關文章
相關標籤/搜索