欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java设计模式(20)之状态模式

程序员文章站 2022-06-17 17:09:42
...

状态模式

允许对象在内部状态改变时,改变它的行为,对象看起来好像修改了它的类。当一个对象的行为改变根据它的状态而改变时,就可以使用状态模式。

类型:

行为型模式(类的状态的行为型模式)

状态模式的几个角色:

具体对象Context:维护具体状态的实例,定义当前的状态
抽象状态对象State:抽象状态接口,定义状态改变时Context对象行为改变的方法
具体状态对象ConcreteState:具体的状态对象,每一种状态对应Context对象的一种具体的行为。

状态模式的关系图:

Java设计模式(20)之状态模式

状态模式示例:

具体对象Context:

/**
 * Create by zhaihongwei on 2018/4/2
 * Context对象
 */
public class LightContext {

    public State state;

    public LightContext() {
        // 灯的默认状态为关闭状态
        this.state = new LightOffState();
    }

    /**
     * 灯的开关,外界没有办法改变灯的打开或者关闭
     * 由灯的状态自己改变
     */
    public void onoffSwitch() {
        state.operationByState(this);
    }
}

抽象状态对象State:

/**
 * Create by zhaihongwei on 2018/4/2
 * 抽象的状态对象
 */
public interface State {

    void operationByState(LightContext light);
}

具体状态对象ConcreteState:(灯的开启状态,灯的关闭状态)

/**
 * Create by zhaihongwei on 2018/4/2
 * 灯的开启状态
 */
public class LightOnState implements State {

    @Override
    /**
     * 灯在打开的情况下,再次按下开关,灯将关闭
     */
    public void operationByState(LightContext light) {
        System.out.println("灯关闭了!");
        // 灯打开(一次点击开关按钮)之后,将灯的开关状态修改为关闭状态
        light.state = new LightOffState();
    }
}
/**
 * Create by zhaihongwei on 2018/4/2
 * 灯的关闭状态
 */
public class LightOffState implements State{

    @Override
    /**
     * 灯在关闭的情况下,再次按下开关,灯将打开
     */
    public void operationByState(LightContext light) {
        System.out.println("灯打开了!");
        // 灯关闭(一次点击开关按钮)之后,将灯的开关状态修改为开启状态
        light.state = new LightOnState();
    }
}

测试类:

/**
 * Create by zhaihongwei on 2018/4/2
 */
public class StateTest {

    public static void main(String[] args) {
        // 创建灯对象
        LightContext lightContext = new LightContext();
        // 按一次开关
        lightContext.onoffSwitch();
        // 再按一次开关
        lightContext.onoffSwitch();
    }
}

测试结果:

灯打开了!
灯关闭了!

总结:

通过上面的例子,可以看到通过状态模式将灯的状态进行了封装,将开灯和关灯的操作委托给了灯的开状态和关状态,随着状态的改变灯的行为也发生了改变。

思考:

如果之前你有学习过策略模式,就会发现状态模式的关系图和策略模式的关系图基本上是一样的,没有看到策略模式的可以看这篇文章:策略模式

虽然说关系图是一样的,但是两种模式的具体关注点是不同的:

  • 对于状态模式:将Context的行为改变封装到了状态对象中,Context的行为随着状态的改变而改变,而外部不需要知道内部状态的具体实现规则,只知道Context的行为改变了(如按了开关之后,知道灯开了,但并不知道灯的状态也改变了)
  • 对于策略模式:通常是外部主动根据具体情况选择了对应的策略(如警察叔叔对象在司机对象吹完酒精检测仪之后,根据结果选择了醉酒驾驶的策略)

状态模式的优缺点:

优点:

  • 将特定状态对应的行为局部化,将不同状态的行为分割开来
  • 将具体的状态改变交由子类来完成,避免了互相之间的依赖

缺点:

  • 具体状态类的增加
相关标签: 状态模式