設計模式:狀態模式

小阿Q的部落格發表於2019-01-27

  遇到這樣的場景時,如: 紅綠燈狀態不同,行人的行為不同。網上購物時,訂單有不同的狀態。

電梯的執行狀態,維修,自動關門,開門,向上,向下等這些不同的狀態對應不同的行為時可以將狀態統一封裝

採用狀態模式來避免程式碼業務的耦合度過高。

  用一句話來描述,狀態模式把所研究的物件的行為包裝在不同物件裡,每一個狀態物件都屬於一個抽象狀態

的子類,狀態模式的意圖是讓一個物件在其內部狀態改變的時候,其行為也隨之改變。

組成:

  環境類(Context):  定義客戶端需要的介面,並且負責具體狀態的切換。
  抽象狀態類(State):  介面或抽象類,負責物件狀態定義,並且封裝環境角色以實現狀態切換。
  具體狀態類(ConcreteState):  具體狀態主要有兩個職責:一是處理本狀態下的事情,二是從本狀態如何過渡到其他狀態。

 

例子:

  模擬一個使用者系統登入,使用者的狀態有,logout,login,當使用者通過賬戶和密碼驗證後狀態為login, 當使用者退出時狀態為logout.

使用抽象狀態類限定了所有的表示不同行為的狀態,它的子類實現了由狀態決定的行為。

/**
 * 抽象狀態類
 */
public interface State {
    void handle();
}

  子類實現

public class UserLoginState implements State {
    @Override
    public void handle() {
        System.out.println("使用者通過密碼驗證狀態login");
    }
}

  

public class UserLogOutState implements State {
    @Override
    public void handle() {
        System.out.println("使用者通過密碼驗證狀態logOut");
    }
}

  環境類持有一個狀態物件,來表示目前的狀態,接受所有狀態相關請求,並委派給具體的狀態物件處理

public class Context {
    //持有狀態物件
    private State state;


    public void setState(State s){
        System.out.println("修改狀態");
        state = s;
        state.handle();
    }
}

  

public class Client {

    public static void main(String[] args) {
        Context ctx = new Context();

        ctx.setState(new UserLoginState());
        ctx.setState(new UserLogOutState());
    }
}

  

修改狀態
使用者通過密碼驗證狀態login
修改狀態
使用者通過密碼驗證狀態logOut

Process finished with exit code 0

  狀態模式達到的效果:

    由於對系統所有的狀態抽象一個子類,當系統變化時,只需要改變所選的子類。同樣如果要新增狀態,也只需要增加新的子類。

    由於沒一個狀態都被包裝到類裡,在程式碼業務處理時省去了大量的if..else判斷。

 使用場景:

  1.當一個物件的行為依賴它所處的狀態,也就是物件的行為隨狀態改變而改變。

  2.當某個方法中存在大量的條件語句,可以考慮把這些條件語句抽象到狀態類中單獨維護。

相關文章