Android中的设计模式之状态模式

参考

  • 《设计模式:可复用面向对象软件的基础 》5.8 State 状态 对象行为型模式
  • 《Android源码设计模式解析与实战》第7章 随遇而安--状态模式

意图

容许一个对象在其内部状态改变时改变它的行为。对象看起来彷佛修改了它的类。java

别名

状态对象(Objects for States)设计模式

适用场景

  • 一个对象的行为取决于它的状态,而且它必须在运行时刻根据状态改变它的行为。
  • 一个操做中含有庞大的多分支的条件语句,且这些操做分支包含这一相同的状态。这个状态一般用一个或多个枚举常量表示。

状态模式将每个条件分支放入到一个独立的类中,这使得你能够根据对象自身的状况将对象状态做为一个对象,这一对象能够不依赖于其它对象而独立变化,这样能够经过多态来去除多的,重复的if-else等分支语句。ide

结构

结构

  • Context 环境类,定义客户须要的接口,维护一个State子类的实例,这个实例定义了当前环境的状态。
  • State 抽象状态类或者状态接口,定义一个或者一组接口,即是该状态下的行为。
  • ConcreteStateA,ConcreteStateB 具体状态类,每个具体的状态类实现抽象State中定义的接口,从而达到不一样状态下的不一样行为。

优势

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

缺点

增长了系统类和对象的个数。spa

应用例子1 电视遥控器

描述

电视的状态分为开机和关机状态,开机能够进行频道切换,调整音量等操做,可是这时重复开机键是无效的;关机状态下,频道切换,调整音量,关机都是无效的操做,只有按开机键会生效。设计

结构

结构

代码实现

/**
 *  电视不一样状态下的相同抽象行为接口
 * @author newtrekWang
 * @email  wangjiaxing20160101@gmail.com
 * @time   2018/8/15  23:30
 */
public interface TvState {
    /**
     * 音量调高
     */
    void turnOn();

    /**
     * 音量调低
     */
    void turnOff();

    /**
     * 下一个频道
     */
    void nextChannel();

    /**
     * 上一个频道
     */
    void preChannel();
}

/**
 *  关机状态下的行为实现
 * @author newtrekWang
 * @email  wangjiaxing20160101@gmail.com
 * @time   2018/8/15  23:22
 */
public class PowerOffState implements TvState {
    @Override
    public void turnOn() {
       // 没有实现即失灵
    }

    @Override
    public void turnOff() {
        // 没有实现即失灵
    }

    @Override
    public void nextChannel() {
        // 没有实现即失灵
    }

    @Override
    public void preChannel() {
        // 没有实现即失灵
    }
}

/**
 *  开机状态下的行为实现
 * @author newtrekWang
 * @email  wangjiaxing20160101@gmail.com
 * @time   2018/8/15  23:22
 */
public class PowerOnState implements TvState {
    @Override
    public void turnOn() {
        System.out.println("音量调高");
    }

    @Override
    public void turnOff() {
        System.out.println("音量调低");
    }

    @Override
    public void nextChannel() {
        System.out.println("切换到了下一个频道");
    }

    @Override
    public void preChannel() {
        System.out.println("切换到了上一个频道");
    }
}

/**
 *  电视机遥控器类
 * @author newtrekWang
 * @email  wangjiaxing20160101@gmail.com
 * @time   2018/8/15  23:29
 */
public class TvController {
    private TvState state;

    public void powerOn(){
        this.state = new PowerOnState();
        System.out.println("已开机");
    }

    public void powerOff(){
        this.state = new PowerOffState();
        System.out.println("已关机");
    }

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

    public void turnOff() {
        state.turnOff();
    }


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

    public void preChannel() {
        state.preChannel();
    }

}

应用例子2 Android源码中的WifiDriverState

后更code

应用例子3 App中的不一样登录状态下的执行行为

好比应用在已登陆状态,点击评论,会正常弹出评论框,而未登陆状态下,则是要跳转到登陆界面登陆后,再正常评论。对象

因此已登陆和未登陆状态下的评论行为是不一样的,这个就能够用状态模式设计。接口

相关文章
相关标签/搜索