介绍
状态模式中的行为是由状态决定的,不同的状态下有不同的行为。状态模式把对象的行为包装在不同的状态对象里面,每一个状态对象都有一个共同的抽象状态基类。状态模式的意图是让一个对象在其内部状态改变的时候,其行为也随之改变。
使用场景
状态模式将每一条件分支放入一个独立的类中,这使得你可以根据自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他的对象而独立变化,这样通过多态去除过多的,重复的if-else等分支语句。
简单实现
电视遥控,关机时候,只有开机键有效,开机的时候,可以选择上一个节目,下一个节目,调大音量,调小音量。
不推荐的写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| public class TvControler {
private static final int POWER_ON = 1; private static final int POWER_OFF= 2;
private int mState = POWER_OFF;
public void powerOn(){
if(mState==POWER_OFF){ System.out.println("开机了"); } mState=POWER_ON;
}
public void powerOff(){
if(mState==POWER_ON){ System.out.println("关机了"); } mState=POWER_OFF;
}
public void nextChannel() { if(mState==POWER_ON){ System.out.println("下一频道了"); }else { System.out.println("两个红灯提示没有开机"); } }
public void preChannel() { if(mState==POWER_ON){ System.out.println("上一频道"); }else { System.out.println("两个红灯提示没有开机"); } }
public void turnUp() { if(mState==POWER_ON){ System.out.println("调大音量"); }else { System.out.println("两个红灯提示没有开机"); } }
public void turnDown() { if(mState==POWER_ON){ System.out.println("关调小音量"); }else { System.out.println("两个红灯提示没有开机"); } }
}
|
在TvController类中,通过mState字段存储了电视的状态,并且在各个操作中根据状态来判断是否应该执行。这就导致了在每个功能中都需要使用if-else,代码重复,相对较为混乱,这是在只有两个状态和简单几个功能函数的情况下,那么当状态变为5个,功能函数变成10个呢,内个函数中都要使用if-else进行判断,而这些代码充斥在一个类中,这些重复的代码无法被提取出来,这使得这个类变得越来越难维护。状态模式就是为了解决这类问题而出现的。
利用状态模式的写法
1 2 3 4 5 6 7 8
| public interface TvState {
public void nextChannel(); public void preChannel(); public void turnUp(); public void turnDown(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class PowerOnState implements TvState { @Override public void nextChannel() { System.out.println("下一个频道"); }
@Override public void preChannel() { System.out.println("上一个频道"); }
@Override public void turnUp() { System.out.println("调大音量"); }
@Override public void turnDown() { System.out.println("调小音量"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class PowerOffState implements TvState { @Override public void nextChannel() {
}
@Override public void preChannel() {
}
@Override public void turnUp() {
}
@Override public void turnDown() {
} }
|
1 2 3 4 5 6 7
| public interface PowerControler {
public void powerOn();
public void powerOff();
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| public class TvControler implements PowerControler {
private TvState tvState;
public void setTvState(TvState tvState){ this.tvState=tvState; }
@Override public void powerOn() { setTvState(new PowerOnState()); System.out.println("开机了。"); }
@Override public void powerOff() { setTvState(new PowerOffState()); System.out.println("关机了。"); }
public void nextChannel(){
tvState.nextChannel(); }
public void preChannel() { tvState.preChannel(); }
public void turnUp() { tvState.turnUp(); }
public void turnDown() { tvState.turnDown(); }
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public static void main(String[] args){
TvControler tvControler = new TvControler();
tvControler.powerOn();
tvControler.nextChannel(); tvControler.preChannel(); tvControler.turnUp(); tvControler.turnDown();
tvControler.powerOff();
tvControler.turnUp();
}
|
打印结果
1 2 3 4 5 6
| 开机了。 下一个频道 上一个频道 调大音量 调小音量 关机了。
|
上一篇:策略模式
下一篇:责任链模式