状态模式

状态模式是对象行为型模式,为了允许一个对象在其内部的状态改变时,修改其行为,这样看起来似乎是修改了它的类一样。状态模式实际上就是统一状态的变化来影响行为,比如一个简单的申请流程,发起-审批-结束,当状态为发起时,该条事务由发起人发起流程;状态为审批时,该条事务变成审批人审批;状态为结束时,该条事务由归档人归档,这个就是状态模式的一种应用。由在我们日常开发时,经常会碰到许多if......else......的情况,同时每个情况里面都需要做复杂的操作,我们会把每个if...else...里面的操作单独抽出来

状态模式的适用性

  • 一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态来改变它的行为。
  • 一个操作中包含大量分支的条件语句,且这些分支依赖于该对象的状态,同时状态分支还有可能继续增加。

状态模式的结构图

java 状态模式状态机 java的状态模式_子类

状态模式中,总共包含三类角色:

1、环境角色(Context):定义了客户感兴趣的接口,同时维护了ConcreteState类的实例,这个实例定义了当前状态。

2、抽象状态角色(State):定义一个接口以封装与Context的一个特定状态相关的行为。

3、具体状态角色(ConcreteState):每一子类实现一个与Context的一个状态相关的行为。 

状态模式示例

  抽象状态角色,定义状态对应的执行方法

public interface State {
    public void handle();
}

  具体状态角色,分别定义状态A和状态B对应的行为

public class ConcreteStateA implements State {
    @Override
    public void handle() {
        System.out.println("状态A执行的操作");
    }
}
public class ConcreteStateB implements State {
    @Override
    public void handle() {
        System.out.println("状态B执行的操作");
    }
}

  环境对象,通过设置不同的状态使得同一种方法执行不同的操作

public class Context {
    private State state;

    public void setState(State state) {
        this.state = state;
    }
    /*用户感兴趣的方法*/
    public void Request() {
        state.handle();
    }
}

  客户端

public class Client {
    public static void main(String[] args) {
        Context context=new Context();
        State concreteStateA=new ConcreteStateA();
        State concreteStateB =new ConcreteStateB();
        /*分别执行状态A状态B对应的操作*/
        context.setState(concreteStateA);
        context.Request();
        context.setState(concreteStateB);
        context.Request();
    }
}
/*
运行结果:
        状态A执行的操作
        状态B执行的操作*/

总结

状态模式一般在业务系统中业务流程的管理上用的比较多,对同一件事务定义不同的状态而执行不同的行为,其次,状态模式使得事务的整体处理上非常清晰,避免了一大片条件判断语句使得代码可读性较差,扩展性不强,同时该模式将状态的变化封装在了类的内部来实现,外界不知道状态是如何处理变化的,但是状态模式需要对每个状态的行为构建一个具体状态类,这样也会使得子类比较多。