狀態機模式實戰

  最近在爲澳洲一家保險公司作web應用,在一個收集用戶地址信息的頁面中,我遇到了一個問題:web

      1.當用戶輸入正確的地址,經過驗證。session

      2.當用戶第一次輸入錯誤的地址,不經過。app

      3.當用戶第二次輸入,不論正確與否,都將經過。ide

      4.當用戶經過後返回上一個頁面若是地址沒有修改,經過。this

                     5.當用戶經過後返回上一個頁面,地址修改,但不正確,不經過spa

  當面對這樣的需求的時候,我立馬有了解決方案,首先要有一個全局變量來保存他輸入的地址是否正確的boolean,而後還得有一個session裏存放一個地址變量,來比較地址是否改變。設計

有了這兩個變量,我就能夠在作驗證的時候來經過判斷這兩個變量的值來決定是否調用驗證方法。第一次驗證,和第二次驗證均可以實現,可是當我想要實現從下個頁面跳回上個頁面的時候,個人驗證邏輯徹底失效了,很明顯簡單的if else和變量已經讓整個程序變得臃腫不堪,邏輯混亂。但通過仔細分析以後,咱們能夠把用戶驗證的狀態分爲:init, happy, retry, unhappy 四個狀態來判斷是否進行地址信息的驗證。以下圖所示:code

                                

經過分析得出四種狀態根據isHappyPath來決定本身狀態的變化,以及決定頁面的跳轉。blog

由此可抽象出狀態類:it

public abstract class State {
    public abstract void changeState(boolean isHappyPath, StateContext stateContext);
}

public class HappyPath extends State {
    @Override
    public void changeState(boolean isHappyPath, StateContext stateContext) {
        if(!isHappyPath){
       errors.reject("address is wrong");  stateContext.setState(
new Retry()); } } } public class Retry extends State { @Override public void changeState(boolean isHappyPath, StateContext stateContext){ if(isHappyPath){ stateContext.setState(new HappyPath()); } else {   stateContext.setState(new UnhappyPath());
     }  } }
public class UnhappyPath extends State{ @Override public void changeState(boolean isHappyPath, StateContext stateContext){ if(isHappyPath) { stateContext.setState(new HappyPath()); } else if(stateContext.isAddressChanged()){
       errors.reject("address is wrong"); stateContext.setState(
new Retry()); } } }

在設計好狀態類和如何切換狀態以後,狀態機container的具體實現以下:

public class StateContext {
    private State state = new Init();

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

    public void changeState(Address address) {
        state.changeState(isHappyPath(address), this);
    }

    public boolean isHappyPath(Address address){
        return addressValidator(address);
    }
}    

 如此簡單的幾個類就構成了狀態機的實現,方便處理了邏輯的轉化以及頁面跳轉的規則。State模式在實際使用中比較多,適合"狀態的切換".由於咱們常常會使用If elseif else 進行狀態切換, 若是針對狀態的這樣判斷切換反覆出現,咱們就要聯想到是否能夠採起State模式了.

  但願能對你們有幫助。

相關文章
相關標籤/搜索