本文主要内容
- 状态模式简介
- 状态模式实例
- 总结
1、状态模式简介
当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类
状态模式的一般使用场景:
- 一个对象的行为取决于它的状态,并且必须在运行时根据它的状态改变它的行为
- 代码中包含大量与状态有关的条件语句,如有很多if else
从第2条来看,状态模式与策略模式类似,但它和策略模式是不一样的,状态模式的所有状态,肯定是有切换的,不同状态不同的行为,遇到不同的环境状态会变化。它的内含偏向于,不同状态下不同的处理逻辑。而策略模式,偏向于同样的功能不同的实现。
状态模式UML图2、状态模式实例
我们以电视遥控器为例。遥控器可以调台,并且调节音量。但电视只有在开机的状态下才能实现上述功能,关机的时候按钮无效。那么我们应该怎么去抽象这个状态类呢?
使用状态模式时,非常重要的一点是分清楚哪里是不同状态下能做的操作?哪些是切换状态的因素。遥控器这个例子中,开关机显示是切换状态的因素,调台和调音量显示是不同状态下的操作。
当我们在定义状态接口时,一定不能把导致状态切换的因素也写到状态接口中,否则会很别扭。这么一分析,状态接口可以这么写:
public interface TvState {
public void nextChannel();
public void preChannel();
public void turnUp();
public void turnDown();
}
开机状态实现:
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("减小音量");
}
}
关机状态什么都不能做,所以这些函数都是空函数:
public class PowerOffState implements TvState{
@Override
public void nextChannel() {
}
@Override
public void preChannel() {
}
@Override
public void turnUp() {
}
@Override
public void turnDown() {
}
}
定义一个开关机的接口:
public interface PowerController {
public void powerOn();
public void powerOff();
}
遥控器:
public class TvController implements PowerController{
TvState mState;
public void setState(TvState tvState){
mState = tvState;
}
@Override
public void powerOn() {
System.out.println("开机了");
setState(new PowerOnState());
}
@Override
public void powerOff() {
System.out.println("关机了");
setState(new PowerOffState());
}
public void nextChannel() {
mState.nextChannel();
}
public void preChannel() {
mState.preChannel();
}
public void turnUp() {
mState.turnUp();
}
public void turnDown() {
mState.turnDown();
}
public static void main(String[] args) {
TvController controller = new TvController();
controller.powerOn();
controller.nextChannel();
controller.turnDown();
controller.powerOff();
controller.turnUp();
}
}
3、总结
示例比较简单,最重要是理解状态模式。尤其是状态模式接口的定义,为啥不把开关机这个方法也写到状态接口当中来呢?因为如果开关机也在状态接口中,那怎么来切换状态呢?导致状态切换的原因一定要放在外面。另外就是认真体会下状态模式和策略模式之间的差异了。策略模式侧面的是不同算法,而状态模式侧重的是不同状态。
网友评论