1. 程式人生 > >設計模式之狀態模式(State Pattern)

設計模式之狀態模式(State Pattern)

簡介:
在狀態模式(State Pattern)中,類的行為是基於它的狀態改變的。這種型別的設計模式屬於行為型模式。
在狀態模式中,我們建立表示各種狀態的物件和一個行為隨著狀態物件改變而改變的 context 物件。
意圖:允許物件在內部狀態發生改變時改變它的行為,物件看起來好像修改了它的類。
主要解決:物件的行為依賴於它的狀態(屬性),並且可以根據它的狀態改變而改變它的相關行為。
何時使用:程式碼中包含大量與物件狀態有關的條件語句。
如何解決:將各種具體的狀態類抽象出來。
關鍵程式碼:通常命令模式的介面中只有一個方法。而狀態模式的介面中有一個或者多個方法。而且,狀態模式的實現類的方法,一般返回值,或者是改變例項變數的值。也就是說,狀態模式一般和物件的狀態有關。實現類的方法有不同的功能,覆蓋介面中的方法。狀態模式和命令模式一樣,也可以用於消除 if…else 等條件選擇語句。
應用例項: 1、打籃球的時候運動員可以有正常狀態、不正常狀態和超常狀態。 2、曾侯乙編鐘中,‘鍾是抽象介面’,'鍾A’等是具體狀態,'曾侯乙編鐘’是具體環境(Context)。
優點: 1、封裝了轉換規則。 2、列舉可能的狀態,在列舉狀態之前需要確定狀態種類。 3、將所有與某個狀態有關的行為放到一個類中,並且可以方便地增加新的狀態,只需要改變物件狀態即可改變物件的行為。 4、允許狀態轉換邏輯與狀態物件合成一體,而不是某一個巨大的條件語句塊。 5、可以讓多個環境物件共享一個狀態物件,從而減少系統中物件的個數。
缺點: 1、狀態模式的使用必然會增加系統類和物件的個數。 2、狀態模式的結構與實現都較為複雜,如果使用不當將導致程式結構和程式碼的混亂。 3、狀態模式對"開閉原則"的支援並不太好,對於可以切換狀態的狀態模式,增加新的狀態類需要修改那些負責狀態轉換的原始碼,否則無法切換到新增狀態,而且修改某個狀態類的行為也需修改對應類的原始碼。
使用場景: 1、行為隨狀態改變而改變的場景。 2、條件、分支語句的代替者。
注意事項:在行為受狀態約束的時候使用狀態模式,而且狀態不超過 5 個。

程式碼:
1.State 介面

public interface State {
    void doAction(Context context);
}

2.實現了 State 介面的實體狀態類

public class StartState  implements State{

    @Override
    public void doAction(Context context) {
        System.out.println("Start。。。。。。");
        context.setState(this);
    }
    
    public String toString() {
        return "Start state";
    }
    
}
public class StopState implements State{

    @Override
    public void doAction(Context context) {
        System.out.println("Stop。。。。。。");
        context.setState(this);
    }

    public String toString() {
        return "Stop state";
    }
}

3.一個帶有某個狀態的類 Context

public class Context {
    private State state;

    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }

    public Context() {
        super();
        this.state=null;
    }
    
}

4.測試

public class Test {
    public static void main(String[] args) {
        Context context=new Context();
        StartState startState=new StartState();
        startState.doAction(context);
        
        StopState stopState=new StopState();
        stopState.doAction(context);
        
        System.out.println(context.getState().toString());
        
        
    }
}

5.測試結果

Start。。。。。。
Stop。。。。。。
Stop state

6.結論
狀態改變了,行為改變。

轉載於:
http://www.runoob.com/design-pattern/state-pattern.html