面向对象的设计模式(六),状态模式

我们是否在敲代码的过程中有过在一个类中写了非常多状态,是否须要依据该对象的不同状态决定该对象的不同行为。

如:我们Android中自己定义一个上拉载入很多其它,下拉刷新的RefreshListView呢?,我们在RefreshListView中定义了三中状态。即:下拉刷新状态。正在刷新,松开刷新。并且这三中不同的状态决定了该自己定义控件能否够下拉等行为。假如你没定义过该控件或者没有写个那种一个对象有多种状态相应控制多种行为也不要紧。由于状态模式非常easy,我们仅仅须要一个样例就知道怎么实现状态模式了。

定义:当一个对象内部状态改变时同意改变其行为,而不用依据不同的状态做过多的if-else推断。而是用不同的类代表不同状态下的行为,这不同的类能够之间不用相互依赖,各自代表不同状态下的行为。

状态模式使用场景:

  1. 一个对象的行为取决于它的状态。并且须要在执行的时候依据不同的状态改变行为。如:我们的RefreshListView。假设当前它的状态是正在刷新,那么它就不可下拉

  2. 代码中包括大量与对象状态相关的if-else语句,一个操作中含有大量的多分支语句if-else或者switch-case语句依赖于该对象的状态的情况。假设是这样的情况,那么代码的可读性不好,且不易改动维护。

状态模式的长处:

  • 使程序的可扩展提高。易于维护。状态模式用一个状态行为类代表一种状态下个行为。摆脱了繁琐的状态推断行为,将繁琐的状态推断转换成结构清晰的状态类集。

状态模式的缺点:

  • 必定使得系统类和对象的个数增多。

代码实现:

电视机行为接口:

/**
 * 电视机行为
 * @author lt
 *
 */
public interface TvAction {
    public void startUp(); // 开机
    public void startOff(); // 关机
    public void nextChannel(); // 下一个频道
    public void prevChannel(); // 上一个频道
}

开机状态行为:

/**
 * 电视机开机状态下的行为
 * @author lt
 *
 */
public class TvStartUpState implements TvAction{

    /**
     * 开机,无效
     */
    @Override
    public void startUp() {

    }

    /**
     * 关机,有效
     */
    @Override
    public void startOff() {
        System.out.println("关机啦!");
    }

    /**
     * 下一个频道,无效
     */
    @Override
    public void nextChannel() {
        System.out.println("切换到下一个频道");
    }

    /**
     * 上一个频道,无效
     */
    @Override
    public void prevChannel() {
        System.out.println("切换到上一个频道");
    }

}

关机状态行为:

/**
 * 电视机关机状态下的行为
 * @author lt
 *
 */
public class TvStartOffState implements TvAction{

    /**
     * 开机。有效
     */
    @Override
    public void startUp() {
        System.out.println("开机啦。");
    }

    /**
     * 关机,无效
     */
    @Override
    public void startOff() {

    }

    /**
     * 下一个频道,无效
     */
    @Override
    public void nextChannel() {

    }

    /**
     * 上一个频道,无效
     */
    @Override
    public void prevChannel() {

    }

}

遥控器:

/**
 * 遥控器
 * @author lt
 *
 */
public class TvController implements TvAction{


    private TvAction tvStartUpState = new TvStartUpState();
    private TvAction tvStartOffState = new TvStartOffState();
    /**
     * 电视机的状态行为,状态即行为,默觉得关机状态
     */
    private TvAction tvState = tvStartOffState;

    @Override
    public void startUp() {
        tvState.startUp();
        this.tvState = tvStartUpState;
    }

    @Override
    public void startOff() {
        tvState.startOff();
        this.tvState = tvStartOffState;
    }

    @Override
    public void nextChannel() {
        tvState.nextChannel();
    }

    @Override
    public void prevChannel() {
        tvState.prevChannel();
    }
}

測试:

public class Test {

    public static void main(String[] args) {
        TvController tvController = new TvController();
        // 开机
        tvController.startUp();
        tvController.nextChannel();
        tvController.prevChannel();

        // 关机
        tvController.startOff();
        tvController.nextChannel();
        tvController.prevChannel();

        // 开机
        tvController.startUp();
        // 关机
        tvController.startOff();
    }
}

结果:

这里写图片描写叙述

 状态模式模拟结束,上面我们測试的时候,我们对电视机的状态频繁切换,并操作了相应状态下的行为,达到了不同状态下对象的行为改变了。

但你是否在上面全部的代码你有看到if-else或者switch-case?没有吧,其实。状态模式就是为了避免过多的if-else和switch-case语句。上面模拟过程中我们看到了电视机的状态行为切换如此简单。

总结:

 状态模式的出现就是为了解决一个对象多种状态下不同行为表现导致出现过多的if-else或者switch-case语句推断切换不同状态下的行为, 通常这样的做法须要设置一个变量记录该对象当前的状态,然后依据变量执行不同的代码。而状态模式根本就不须要if-else和switch-case,一个对象类代表一种状态下的行为表现。当状态切换时切换不同的对象类就可以,达到状态即行为的效果。

态模式的使用和没有使用状态模式的if-else/switch-case控制行为的关系有点像c是面向过程而java面向对象的关系一样

posted @ 2017-07-06 19:51  yangykaifa  阅读(736)  评论(0编辑  收藏  举报