狀態模式——一個狀態一個行爲

目錄

一、基礎簡介

1、定義

2、使用場景

3、優缺點

4、模式結構

二、實例的代碼實現

1、State類,抽象狀態類

2、ConcreteStateA 具體狀態類

3、Context 維護一個ConcreteState子類的實例

4、客戶端

5、結果


一、基礎簡介

1、定義

允許對象在內部狀態發生改變時改變它的行爲,對象看起來好像修改了它的類。

2、使用場景

一個對象的行爲取決於它的狀態,並且它必須在運行時刻根據狀態改變它的行爲時,同時代碼中包含大量與對象狀態有關的條件語句,就可以使用狀態模式

3、優缺點

優點:

  •  1、封裝了轉換規則。
  • 2、枚舉可能的狀態,在枚舉狀態之前需要確定狀態種類。
  • 3、將所有與某個狀態有關的行爲放到一個類中,並且可以方便地增加新的狀態,只需要改變對象狀態即可改變對象的行爲。
  • 4、允許狀態轉換邏輯與狀態對象合成一體,而不是某一個巨大的條件語句塊。
  • 5、可以讓多個環境對象共享一個狀態對象,從而減少系統中對象的個數。

缺點:

  •  1、狀態模式的使用必然會增加系統類和對象的個數。
  • 2、狀態模式的結構與實現都較爲複雜,如果使用不當將導致程序結構和代碼的混亂。
  • 3、狀態模式對"開閉原則"的支持並不太好,對於可以切換狀態的狀態模式,增加新的狀態類需要修改那些負責狀態轉換的源代碼,否則無法切換到新增狀態,而且修改某個狀態類的行爲也需修改對應類的源代碼。

4、模式結構

1、上下文環境(Context):它定義了客戶程序需要的接口並維護一個具體狀態角色的實例,將與狀態相關的操作委託給當前的Concrete State對象來處理。

2、抽象狀態(State):定義一個接口以封裝使用上下文環境的的一個特定狀態相關的行爲。

3、具體狀態(Concrete State):實現抽象狀態定義的接口。

二、實例的代碼實現

1、State類,抽象狀態類

package com.mfc.design.狀態模式;

/**
 * @author MouFangCai
 * @date 2019/10/17 15:36
 */
public interface State {

    // 定義一個接口以封裝與Context的一個特定狀態相關的行爲
    public void doAction(Context context);

}

2、ConcreteStateA 具體狀態類

package com.mfc.design.狀態模式;

/**
 * @author MouFangCai
 * @date 2019/10/17 15:42
 *
 * 具體狀態類,每一個子類實現一個與context的一個狀態相關的行爲
 */
public class ConcreteStateA implements State {
    @Override
    public void doAction(Context context) {
        System.out.println("stateA處理完成,轉到下一個狀態");
        context.setState(new ConcreteStateB());
    }

}
package com.mfc.design.狀態模式;

/**
 * @author MouFangCai
 * @date 2019/10/17 15:42
 */
public class ConcreteStateB implements State {
    @Override
    public void doAction(Context context) {
        System.out.println("stateB處理完成,轉到下一個狀態");
        context.setState(new ConcreteStateA());
    }
    
}

3、Context 維護一個ConcreteState子類的實例

package com.mfc.design.狀態模式;

/**
 * @author MouFangCai
 * @date 2019/10/17 15:37
 */
public class Context {

    private State state;

    public State getState() {
        return state;
    }

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

    // 對請求做處理,並設置下一個狀態
    public void doAction(){
        state.doAction(this);
    }
}

4、客戶端

package com.mfc.design.狀態模式;

/**
 * @author MouFangCai
 * @date 2019/10/17 15:58
 */
public class Client_State {

    public static void main(String[] args) {
        Context context = new Context();
        // 設置context的初始狀態爲 ConcreteStateA
        context.setState(new ConcreteStateA());

        // 不斷的請求,同時更改狀態
        context.doAction();
        context.doAction();

    }
}

5、結果

stateA處理完成,轉到下一個狀態
stateB處理完成,轉到下一個狀態

Process finished with exit code 0

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章