状态机模式实战

  最近在为澳洲一家保险公司作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模式了.

  但愿能对你们有帮助。

相关文章
相关标签/搜索