目錄
3、Context 維護一個ConcreteState子類的實例
一、基礎簡介
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