[设计模式]状态模式

开始写设计模式系列,希望自己可以坚持下来.
第六篇:状态模式

什么是状态模式

当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。


很多人都会疑问状态模式和策略模式的区别在哪?实际上状态模式和策略模式很相似,甚至他们的UML图都是一致的,那么他们的区别在哪呢?我们再来回想下策略模式,

  • 策略模式:创建一个策略的抽象,在这个接口声明算法函数,创建不同的策略实现类来实现算法,在Context类里,外部模块通过更换不同的策略实现从而达到不同的效果。策略模式的行为是相互独立的,可以相互替换的。
  • 状态模式:状态模式的创建过程和策略模式一致,但是他的目的和意图却完全不同,状态模式的意图是让一个对象在其内部状态改变的时候,其行为也随之改变。用户不应该来指定状态(除了初始状态),而是在满足一定条件下内部将其状态自动切换。

火车的状态模式:

在生活中火车经历的状态一般是从发车->加速->减速->加速…..->减速->停车,那么我们来实现它:
State状态接口:

package top.huyuxin.statemodel;

public interface State {

  abstract void run(int speed);

}

发车状态:

package top.huyuxin.statemodel;

public class StartState implements State {

    @Override
    public void run(int speed) {
        // 当前为发车状态,火车开始提速
        System.out.println("火车开车正在提速!");
        Context.Handle.getInstance().setState(new SpeedState());
    }
}

加速状态:


package top.huyuxin.statemodel;

public class SpeedState implements State {

    @Override
    public void run(int speed) {
        if(speed>=350){
            System.out.println("到达时速上限,开始减速!");
            Context.Handle.getInstance().setState(new SlowState());
        }else{
            System.out.println("火车当前时速:"+speed+",正在加速!");
            Context.Handle.getInstance().speed+=50;
        }
    }

}

减速状态:


package top.huyuxin.statemodel;

public class SlowState implements State {

    @Override
    public void run(int speed) {
        if(speed<250){
            System.out.println("到达时速下限,开始减速!");
            Context.Handle.getInstance().setState(new SpeedState());
        }else{
            System.out.println("火车当前时速:"+speed+",正在减速!");
            Context.Handle.getInstance().speed-=50;
        }
    }

}

停车状态:


package top.huyuxin.statemodel;

public class StopState implements State{

    @Override
    public void run(int speed) {
        System.out.println("火车准备停靠,开始减速,当前时速:"+speed);
        Context.Handle.getInstance().speed-=50;
        if(Context.Handle.getInstance().speed==0){
            System.out.println("火车停止运行停靠成功!");
        }
    }


}

Context:


package top.huyuxin.statemodel;

public class Context {

    public int speed=0;//时速
    public int distance=0;//距离

    private Context() {
        super();
    }

    public static class Handle{
        private static Context context=new Context();
        public static Context getInstance() {
            return context;
        }
    }

    private State state;

    /**
     * protected 防止外部模块修改状态
     * @param state
     */
    protected void setState(State state) {
        this.state = state;
    }

    public void run(){
        if(state==null){
            state=new StartState();
        }
        for(;;){
            state.run(speed);
            distance+=10;
            //开始停靠
            if(distance>300){
                state=new StopState();
                if(speed==-50){
                    break;
                }
            }
        }
    }
}

Main:

package top.huyuxin.statemodel.main;

import top.huyuxin.statemodel.Context;
import top.huyuxin.statemodel.Context.Handle;

public class Main {

    public static void main(String[] args) {

        Context.Handle.getInstance().run();

    }
}

输出:


火车开车正在提速!
火车当前时速:0,正在加速!
火车当前时速:50,正在加速!
火车当前时速:100,正在加速!
火车当前时速:150,正在加速!
火车当前时速:200,正在加速!
火车当前时速:250,正在加速!
火车当前时速:300,正在加速!
到达时速上限,开始减速!
火车当前时速:350,正在减速!
火车当前时速:300,正在减速!
火车当前时速:250,正在减速!
到达时速下限,开始减速!
火车当前时速:200,正在加速!
火车当前时速:250,正在加速!
火车当前时速:300,正在加速!
到达时速上限,开始减速!
火车当前时速:350,正在减速!
火车当前时速:300,正在减速!
火车当前时速:250,正在减速!
到达时速下限,开始减速!
火车当前时速:200,正在加速!
火车当前时速:250,正在加速!
火车当前时速:300,正在加速!
到达时速上限,开始减速!
火车当前时速:350,正在减速!
火车当前时速:300,正在减速!
火车当前时速:250,正在减速!
到达时速下限,开始减速!
火车当前时速:200,正在加速!
火车当前时速:250,正在加速!
火车准备停靠,开始减速,当前时速:300
火车准备停靠,开始减速,当前时速:250
火车准备停靠,开始减速,当前时速:200
火车准备停靠,开始减速,当前时速:150
火车准备停靠,开始减速,当前时速:100
火车准备停靠,开始减速,当前时速:50
火车停止运行停靠成功!

其实经过这样简单的倒腾这已经是一个简易的有限状态机。当然按关于简易有限状态机的实现,网上还有一种利用enum(枚举)的实现方式,当状态比较简单还是可以使用的,但是状态过多时不建议使用,这会使得代码的可读性变得十分差。

扩展

在我们生活中还有很多的在这种情况,比如电梯在运行时他的状态应该是,开门->关门->升降->停止->开门->关门,在升降的过程中是不可能执行开门状态的,关门和开门进行时却可以自由切换,等等这些复杂的状态处理。我们可以通过建立链表关系,二叉树等数据结构的关系来实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值