状态模式

随遇而安-状态模式

模式简介

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

使用场景

  • 一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为
  • 代码中包含大量与对象状态有关的条件语句,例如:一个操作中含有庞大的多分支语句(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();
    }
}

执行结果

stateMode.png

总结

不同状态下对于同一行为有不同的相应,这其实就是一个将if-else用多态来实现的一个具体示例

优点

​ 模式将所有与一个特定状态相关的行为都放入在一个状态对象中,它提供了一个更好的方法来组织与特定状态相关的代码,将繁琐的状态判断转换成结构清晰的状态类簇,在避免代码膨胀的同时也保证了可扩展性与可维护性

缺点

​ 模式的使用必然会增加系统类和对象的个数