您的位置:首页 > 其它

[设计模式]状态模式

2017-09-17 13:11 204 查看
开始写设计模式系列,希望自己可以坚持下来.

第六篇:状态模式

什么是状态模式

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

很多人都会疑问状态模式和策略模式的区别在哪?实际上状态模式和策略模式很相似,甚至他们的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(枚举)的实现方式,当状态比较简单还是可以使用的,但是状态过多时不建议使用,这会使得代码的可读性变得十分差。

扩展

在我们生活中还有很多的在这种情况,比如电梯在运行时他的状态应该是,开门->关门->升降->停止->开门->关门,在升降的过程中是不可能执行开门状态的,关门和开门进行时却可以自由切换,等等这些复杂的状态处理。我们可以通过建立链表关系,二叉树等数据结构的关系来实现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: