面向對象的設計模式(六),狀態模式

咱們是否在敲代碼的過程當中有過在一個類中寫了很是多狀態,是否需要依據該對象的不一樣狀態決定該對象的不一樣行爲。java

如:咱們Android中本身定義一個上拉載入不少其它,下拉刷新的RefreshListView呢?,咱們在RefreshListView中定義了三中狀態。即:下拉刷新狀態。正在刷新,鬆開刷新。而且這三中不一樣的狀態決定了該本身定義控件可否夠下拉等行爲。假如你沒定義過該控件或者沒有寫個那種一個對象有多種狀態相應控制多種行爲也沒關係。因爲狀態模式很是easy,咱們僅僅需要一個樣例就知道怎麼實現狀態模式了。markdown

定義:當一個對象內部狀態改變時贊成改變其行爲,而不用依據不一樣的狀態作過多的if-else推斷。而是用不一樣的類表明不一樣狀態下的行爲,這不一樣的類可以之間不用相互依賴,各自表明不一樣狀態下的行爲。ide

狀態模式使用場景:post

  1. 一個對象的行爲取決於它的狀態。而且需要在執行的時候依據不一樣的狀態改變行爲。如:咱們的RefreshListView。假設當前它的狀態是正在刷新,那麼它就不可下拉this

  2. 代碼中包括大量與對象狀態相關的if-else語句,一個操做中含有大量的多分支語句if-else或者switch-case語句依賴於該對象的狀態的狀況。假設是這樣的狀況,那麼代碼的可讀性很差,且不易改動維護。spa

狀態模式的長處:code

  • 使程序的可擴展提升。易於維護。狀態模式用一個狀態行爲類表明一種狀態下個行爲。擺脫了繁瑣的狀態推斷行爲,將繁瑣的狀態推斷轉換成結構清晰的狀態類集。

狀態模式的缺點:對象

  • 一定使得系統類和對象的個數增多。

代碼實現:接口

電視機行爲接口:圖片

/** * 電視機行爲 * @author lt * */
public interface TvAction {
    public void startUp(); // 開機
    public void startOff(); // 關機
    public void nextChannel(); // 下一個頻道
    public void prevChannel(); // 上一個頻道
}

開機狀態行爲:

/** * 電視機開機狀態下的行爲 * @author lt * */
public class TvStartUpState implements TvAction{

    /** * 開機,無效 */
    @Override
    public void startUp() {

    }

    /** * 關機,有效 */
    @Override
    public void startOff() {
        System.out.println("關機啦!");
    }

    /** * 下一個頻道,無效 */
    @Override
    public void nextChannel() {
        System.out.println("切換到下一個頻道");
    }

    /** * 上一個頻道,無效 */
    @Override
    public void prevChannel() {
        System.out.println("切換到上一個頻道");
    }

}

關機狀態行爲:

/** * 電視機關機狀態下的行爲 * @author lt * */
public class TvStartOffState implements TvAction{

    /** * 開機。有效 */
    @Override
    public void startUp() {
        System.out.println("開機啦。");
    }

    /** * 關機,無效 */
    @Override
    public void startOff() {

    }

    /** * 下一個頻道,無效 */
    @Override
    public void nextChannel() {

    }

    /** * 上一個頻道,無效 */
    @Override
    public void prevChannel() {

    }

}

遙控器:

/** * 遙控器 * @author lt * */
public class TvController implements TvAction{


    private TvAction tvStartUpState = new TvStartUpState();
    private TvAction tvStartOffState = new TvStartOffState();
    /** * 電視機的狀態行爲,狀態即行爲,默以爲關機狀態 */
    private TvAction tvState = tvStartOffState;

    @Override
    public void startUp() {
        tvState.startUp();
        this.tvState = tvStartUpState;
    }

    @Override
    public void startOff() {
        tvState.startOff();
        this.tvState = tvStartOffState;
    }

    @Override
    public void nextChannel() {
        tvState.nextChannel();
    }

    @Override
    public void prevChannel() {
        tvState.prevChannel();
    }
}

測試:

public class Test {

    public static void main(String[] args) {
        TvController tvController = new TvController();
        // 開機
        tvController.startUp();
        tvController.nextChannel();
        tvController.prevChannel();

        // 關機
        tvController.startOff();
        tvController.nextChannel();
        tvController.prevChannel();

        // 開機
        tvController.startUp();
        // 關機
        tvController.startOff();
    }
}

結果:

這裏寫圖片描寫敘述

 狀態模式模擬結束,上面咱們測試的時候,咱們對電視機的狀態頻繁切換,並操做了相應狀態下的行爲,達到了不一樣狀態下對象的行爲改變了。

但你是否在上面所有的代碼你有看到if-else或者switch-case?沒有吧,其實。狀態模式就是爲了不過多的if-else和switch-case語句。上面模擬過程當中咱們看到了電視機的狀態行爲切換如此簡單。

總結:

 狀態模式的出現就是爲了解決一個對象多種狀態下不一樣行爲表現致使出現過多的if-else或者switch-case語句推斷切換不一樣狀態下的行爲, 一般這樣的作法需要設置一個變量記錄該對象當前的狀態,而後依據變量執行不一樣的代碼。而狀態模式根本就不需要if-else和switch-case,一個對象類表明一種狀態下的行爲表現。當狀態切換時切換不一樣的對象類就能夠,達到狀態即行爲的效果。

態模式的使用和沒有使用狀態模式的if-else/switch-case控制行爲的關係有點像c是面向過程而java面向對象的關係同樣

相關文章
相關標籤/搜索