随遇而安-状态模式
模式简介
当一个对象内在状态改变时允许改变其行为,这个对象看起来像是改变了其类
使用场景
- 一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为
- 代码中包含大量与对象状态有关的条件语句,例如:一个操作中含有庞大的多分支语句(if-else switch-case),且这些分支依赖于该对象的状态
状态模式将每一个条件分支放入一个独立的类中,这使得你可以根据对象自身的情况将对象的状态作为一个对象,这个对象可以不依赖与其他对象而独立变化,这样通过多态来去除过多的重复的if-else等分支语句。
简单实现
以电视遥控器为例子
电视状态接口
1
2
3
4
5
6
|
public interface TvState {
public void nextChannel();
public void prevChannel();
public void turnUp();
public void turnDown();
}
|
关机状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class PowerOffState implements TvState {
public void nextChannel() {
}
public void prevChannel() {
}
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
|
public class PowerOnState implements TvState {
public void nextChannel() {
System.out.println("下一频道");
}
public void prevChannel() {
System.out.println("上一频道");
}
public void turnUp() {
System.out.println("提高音量");
}
public void turnDown() {
System.out.println("降低音量");
}
}
|
电源操作接口
1
2
3
4
|
public interface PowerController {
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
|
public class TvController implements PowerController {
private TvState tvState;
public void setTvState(TvState tvState){
this.tvState=tvState;
}
public void powerOn() {
setTvState(new PowerOnState());
System.out.println("开机了");
}
public void powerOff() {
setTvState(new PowerOffState());
System.out.println("关机了");
}
public void nextChannel(){
tvState.nextChannel();
}
public void prevChannel(){
tvState.prevChannel();
}
public void turnUp(){
tvState.turnUp();
}
public void turnDown(){
tvState.turnDown();
}
}
|
客户端调用
1
2
3
4
5
6
7
8
9
10
11
|
public class Client {
public static void main(String[] args) {
TvController tvController=new TvController();
tvController.powerOn();
tvController.nextChannel();
tvController.prevChannel();
tvController.turnUp();
tvController.powerOff();
tvController.turnUp();
}
}
|
执行结果

总结
不同状态下对于同一行为有不同的相应,这其实就是一个将if-else用多态来实现的一个具体示例
优点
模式将所有与一个特定状态相关的行为都放入在一个状态对象中,它提供了一个更好的方法来组织与特定状态相关的代码,将繁琐的状态判断转换成结构清晰的状态类簇,在避免代码膨胀的同时也保证了可扩展性与可维护性
缺点
模式的使用必然会增加系统类和对象的个数