《状态模式》
我们经常使用if-else来应付状态的切换,这样往往会导致程序难以阅读、维护和扩展,假设我们现在要模拟交通灯的切换,顺序是绿灯-黄灯-红灯-绿灯...,我们先用if-else来模拟一下:
private int state = 0;
public void change(){
if (state==0){
System.out.println("显示绿灯");
state++;
}else if(state==1){
System.out.println("显示红灯");
state++;
}else if(state==2){
System.out.println("显示黄灯");
state=0;
}
}
咋一看,这个if-else还不是很复杂,但是如果很多颜色的灯光,那就变得非常不易于维护或扩展。状态模式就是解决这种控制一个对象状态转换的条件表达式过于的复杂的情况,
把状态的判断逻辑转义到不同状态的一系列类当中,可以把复杂的逻辑判断简化。
状态模式的类结构:
用状态模式重新实现上面的场景:
//抽象状态类,可以是接口或抽象类
public interface State {
void show();
}
//具体状态
public class GreenState implements State {
private TrafficLight tl;
public GreenState(TrafficLight tl) {
this.tl = tl;
}
@Override
public void show() {
System.out.println("显示绿灯");
tl.setState(tl.getYs());
}
}
public class YellowState implements State {
private TrafficLight tl;
public YellowState(TrafficLight tl) {
this.tl = tl;
}
@Override
public void show() {
System.out.println("显示黄灯");
tl.setState(tl.getRs());
}
}
public class RedState implements State {
private TrafficLight tl;
public RedState(TrafficLight tl) {
this.tl = tl;
}
@Override
public void show() {
System.out.println("显示红灯");
tl.setState(tl.getGs());
}
}
//Context
public class TrafficLight {
private GreenState gs;
private RedState rs;
private YellowState ys;
private State s;
public TrafficLight() {
gs = new GreenState(this);
rs = new RedState(this);
ys = new YellowState(this);
s = gs;//设置初始状态为绿灯
}
public void setState(State state){
this.s = state;
}
//该方法调用的是状态类的方法
public void change(){
s.show();
}
public GreenState getGs() {
return gs;
}
public RedState getRs() {
return rs;
}
public YellowState getYs() {
return ys;
}
}
总结
1.何时使用状态模式:当一个对象的行为取决于它的状态,并且它必须在运行时根据状态的改变而改变它的行为,这时候就可以考 虑使用状态模式了。当然并不是所有涉及到状态切换的都要使用状态模式,它也有缺点:比如会导致类的数量过多
2.对象的状态和行为:状态可以理解为就是类的实例变量,而行为就是类的方法,状态模式下,类的行为是随着状态的改变而改变 的,即状态决定行为
3.状态模式和策略模式的区别:这两个模式的类图几乎一样,确实他们很相似,都用到了组合,最大的区别就是策略模式通过行为 或算法配置Context类,而状态模式则是允许Context随着状态的改变而改变行为