[Fun] design patterns series of state [mode]

1 Introduction

State model (the Pattern State), when the object is an intrinsic 状态改变allowed time 改变行为, the object looks like a change of its class. In short, that is 状态的变更引起了行为的变更.

2. graphic

The following figure four cars, each representing four states everyday car.
Open state:

Closed state:

Flying status:

Stop status:

Wherein, under certain condition, there may perform four operations, namely, open, close, run, stop, and then do the corresponding handled shown below.

3. Case realization

FIG class as follows:

  • Automotive abstract class defines the state CarStateholding type Contextattributes, perform operation while holding four, open, close, run, stopmethod;
  • Subclassing abstract state class cars OpenningState, , ClosingState, RunningState, StoppingStaterepresenting the open state, closed state, the flying state, stop state;
  • Define the role of class environment Context, the state of the object declared as a static constant, there are several state of the object to declare several static constant environmental role has all acts of state abstract roles defined, specific implementation using on commission. Specific environmental role has two responsibilities: the state must deal with this task, you can decide whether to transition to other states.

Code is implemented as follows:

package com.wzj.state.example1;

/**
 * @Author: wzj
 * @Date: 2019/11/3 20:10
 * @Desc: 汽车状态抽象类
 */
public abstract class CarState {
    //环境角色,封装状态变化引起的行为变化
    protected Context context;

    public void setContext(Context context) {
        this.context = context;
    }

    //汽车开门动作
    public abstract void open();

    //汽车关门动作
    public abstract void close();

    //汽车飞奔动作
    public abstract void run();

    //汽车停止动作
    public abstract void stop();

}
package com.wzj.state.example1;

/**
 * @Author: wzj
 * @Date: 2019/11/3 20:23
 * @Desc: 汽车开门状态类
 */
public class OpenningState extends CarState {

    //打开汽车门
    public void open() {
        System.out.println("汽车门已开");
    }

    //关闭汽车门
    public void close() {
        //状态修改
        super.context.setCarState(Context.closingState);
        //动作委托为ClosingState来执行
        super.context.getCarState().close();
    }

    //门开着时汽车一般不奔跑
    public void run() {
        System.out.println("汽车开门状态,不能奔跑");
    }

    //车门开着时,切换不到停止状态,因为没有四种状态中,没有开门且停止这个状态
    public void stop() {
        System.out.println("汽车开门状态,不能长时间开着门且处于停止状态");

    }
}
package com.wzj.state.example1;

/**
 * @Author: wzj
 * @Date: 2019/11/3 20:23
 * @Desc: 汽车飞奔状态类
 */
public class RunningState extends CarState {

    //打开奔跑时不开门
    public void open() {
        System.out.println("车在飞奔,不能打开");
    }

    //奔跑时肯定是关门的
    public void close() {
        System.out.println("车在飞奔,已经关闭,不能再次关闭");
    }

    //汽车在飞奔
    public void run() {
        System.out.println("汽车在飞奔");
    }

    //汽车可以停下来
    public void stop() {
        //修改汽车为停止状态
        super.context.setCarState(Context.stoppingState);
        //停止动作委托为StoppingState类来执行
        super.context.getCarState().stop();
    }
}
package com.wzj.state.example1;

/**
 * @Author: wzj
 * @Date: 2019/11/3 20:23
 * @Desc: 汽车关门状态类
 */
public class ClosingState extends CarState {

    //打开汽车门
    public void open() {
        //修改汽车为开门状态
        super.context.setCarState(Context.openningState);
        //动作委托为OpenningState类来执行
        super.context.getCarState().open();
    }

    //关闭汽车门
    public void close() {
        System.out.println("汽车门已关");
    }

    //汽车在飞奔
    public void run() {
        //修改汽车为飞奔状态
        super.context.setCarState(Context.runningState);
        //动作委托为RunningState类来执行
        super.context.getCarState().run();

    }

    //汽车在停止
    public void stop() {
        //设置汽车状态为停止状态
        super.context.setCarState(Context.stoppingState);
        //动作委托为StoppingState类来执行
        super.context.getCarState().stop();

    }
}
package com.wzj.state.example1;

/**
 * @Author: wzj
 * @Date: 2019/11/3 20:19
 * @Desc: 上下文环境类
 */
public class Context {

    /**列出汽车所有状态
     * openningState-开门状态 closingState-关门状态
     * runningState-奔驰状态 stoppingState-停止状态
     */
    public static final OpenningState openningState = new OpenningState();
    public static final ClosingState closingState = new ClosingState();
    public static final RunningState runningState = new RunningState();
    public static final StoppingState stoppingState = new StoppingState();

    //定义汽车当前状态
    private CarState carState;

    public CarState getCarState() {
        return  carState;
    }

    public void setCarState(CarState carState) {
        this.carState = carState;
        //切换状态
        this.carState.setContext(this);
    }

    //汽车开门
    public void open() {
        this.carState.open();
    }

    //汽车关门
    public void close(){
        this.carState.close();
    }

    //汽车飞奔
    public void run(){
        this.carState.run();
    }

    //汽车停止
    public void stop(){
        this.carState.stop();
    }

}

Client class as follows:

package com.wzj.state.example1;

/**
 * @Author: wzj
 * @Date: 2019/11/3 21:06
 * @Desc:
 */
public class Client {
    public static void main(String[] args) {
        Context context = new Context();
        context.setCarState(new OpenningState());
//        context.setCarState(new ClosingState());
//        context.setCarState(new RunningState());
//        context.setCarState(new StoppingState());
        context.open();
//        context.close();
//        context.run();
//        context.stop();
    }
}

Performed as follows:
When only the opening Client15 when the rows, respectively, open the code lines 11, 12, get the following result:
car-door-open state, the open execution

Automobile is closed state, the implementation of open

When the car is flying state, to perform open

When the car is stopped, the implementation of open

The results can be seen, the implementation of a similar openmethod, resulting in a change of behavior when a change of state.

4. The state pattern summarized

advantage

  • 结构清晰
    避免了过多的switch...case或者if...else语句的使用,避免了程序的复杂性,提高系统的可维护性;
  • 遵循设计原则
    很好地体现了开闭原则和单一职责原则,每个状态都是一个子类,你要增加状态就要增加子类,你要修改状态,你只修改一个子类就可以了。
  • 封装性非常好
    这也是状态模式的基本要求,状态变换放置到类的内部来实现,外部的调用不用知道类内部如何实现状态和行为的变换。
    缺点
    状态模式既然有优点,那当然有缺点了。但只有一个缺点,子类会太多,也就是类膨胀。如果一个事物有很多个状态也不稀奇,如果完全使用状态模式就会有太多的子类,不好管理,这个需要大家在项目中自己衡量。其实有很多方式可以解决这个状态问题,如在数据库中建立一个状态表,然后根据状态执行相应的操作,这个也不复杂,看大家的习惯和嗜好了。

Guess you like

Origin www.cnblogs.com/father-of-little-pig/p/12130821.html