设计模式-状态模式


介绍

  • 状态模式的行为是由状态来决定的,不同状态下有不同的行为。

  • 状态模式和策略模式的结构几乎完全一样,但是他们的目的,本质却完全不一样:

    • 区别: 状态模式的行为是平行的,不可替换的,策略模式的行为是彼此独立,可以相互替换的

    • 描述:状态模式把对象的行为包装在不同的状态对象里,每一个状态对象都有一个共同的抽象状态积累。状态模式的意图是让每一个对象在其内部 状态改变的时候,行为也随之改变

定义

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

使用场景

  • 一个对象的行为取决于他的状态,并且他必须在运行时根据状态改变他的行为
  • 代码中大量与状态有关的语句,例如:一个操作中含有庞大的分支语句,且这些分支依赖于该对象的状态
  • 状态模式将每一个条件分支放入一个独立的类中,这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖其他对象而独立变化,这样通过多态来去除过多的,重复的 if-else 分支语句

UML图解 (待补充)


代码示例

  • 普通实现
  public class TvController {

    private static int BASE_STATE = 0;
    private final static int POWER_OFF = BASE_STATE + 1;
    private final static int POWER_ON = BASE_STATE + 2;
    private int mState = POWER_OFF;

    public void powerOn() {
        mState = POWER_ON;
        if (mState == POWER_OFF) {
            System.out.println("开机");
        }
    }

    public void powerOff() {
        mState = POWER_OFF;
        if (mState == POWER_ON) {
            System.out.println("关机");
        }
    }

    public void nextChannel() {
        if (mState == POWER_ON) {
            System.out.println("下一个频道");
        } else {
            System.out.println("error tv is powerOff !!");
        }
    }

    public void prevChannel() {
        if (mState == POWER_ON) {
            System.out.println("上一个频道");
        } else {
            System.out.println("error tv is powerOff !!");
        }
    }

    public void turnOn() {
        if (mState == POWER_ON) {
            System.out.println("调高音量");
        } else {
            System.out.println("error tv is powerOff !!");
        }
    }

    public void turnDown() {
        if (mState == POWER_ON) {
            System.out.println("调低音量");
        } else {
            System.out.println("error tv is powerOff !!");
        }
    }

}

可以看到,在TVController类中,通过mState来存储电视的状态,并且在各个操作中都需要通过if-else来判断状态,代码重复,相对较为混乱

  • 状态模式实现

使用状态模式:将这些状态用对象来代替,将这些行为封装到对象中,是的不同的状态下有不同的实现,这样就将这些if-else 从TVController类
去掉,整个代码也看起来清晰起来。

  • TvState.java : 抽象类 实现Tv相关操作
  public interface TvState {
    public void nextChannel();
    public void prevChannel();
    public void turnUp();
    public void turnDown();
}
  • PowerOffState.java :关机状态实现类
  public class PowerOfferState implements TvState {

    @Override
    public void nextChannel() {
    }

    @Override
    public void prevChannel() {
    }

    @Override
    public void turnOn() {
    }

    @Override
    public void turnDown() {
    }
}
  • PowerOnState.java :开机状态实现类
  public class PowerOnState implements TvState {

    @Override
    public void nextChannel() {
        print("下一频道");
    }

    @Override
    public void    prevChannel() {
        print("上一频道");
    }

    @Override
    public void turnOn() {
        print("调高音量");
    }

    @Override
    public void turnDown() {
        print("调低音量");
    }

    private void print(String msg) {
        System.out.println(msg);
    }
    
}
  • PowerController.java : 开关机控制抽象类
  public interface PowerController {

    public TvState mState;
    public void setState(TvState state);
    public void powerOn();    
    public void powerOff();
}
  • TvControllerImp.java
  public class TvControllerImp implements PowerController {

    @Override
    public void setState(TvState state) {
        mState = state;
    }

    @Override
    public void powerOn() {
        setState(new PowerOnState());

        System.out.println("开机");
    }

    @Override
    public void powerOff() {
        setState(new PowerOffState());

        System.out.println("关机");
    }

    public void nextChannel() {
        mState.nextChannel();
    }

    public void prevChannel() {
        mState.prevChannel();
    }

    public void turnOn() {
        mState.turnOn();
    }

    public void turnDown() {
        mState.turnDown();
    }
}
  • 测试代码
  public class TvClient {
    public static void main(String[] args) {
        TvControllerImp tv = new TvControllerImp();
        // 开机
        tv.powerOn();
        // 下一个频道
        tv.nextChannel();
        // 调高音量
        tv.turnOn();
        // 调低音量
        tv.turnDown();
        // 关机
        tv.powerOff();
        // 调高音量,电视不响应
        tv.turnOn();
    }
}
  • Android中的应用实例--WiFi管理
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容