×
广告

Android设计模式-7-状态模式

96
今阳说
2018.06.05 23:09 字数 348

1. 定义:

当一个对象的内在状态改变时,其行为也随之改变

2. 适用场景:

  1. 一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。
  2. 一个操作中含有庞大的多分支结构,并且这些分支决定于对象的状态。

3. 优缺点:

  • 优点:
    将繁琐的状态判断转换成结构清晰的状态类族,在避免代码膨胀的同时也保证了可扩展性和可维护性
  • 缺点:
    会增加系统类和对象的个数

4. android源码中的使用

WifiSettings中wifi的不同状态

5. 实例演示

以电视遥控器为例,分为开机状态和关机状态,普通的写法可能是如下这样,使用if-else去判断不同的状态

//遥控器类
class TvControler {
        //开机状态
        private final static int POWER_ON = 1;
        //关机状态
        private final static int POWER_OFF = 2;
        //记录状态,默认为关
        private int mState = POWER_OFF;

        public void powerOnOFF() {
            if (mState == POWER_OFF) {
                mState = POWER_ON;
                LjyLogUtil.i("开机啦~~");
            } else {
                mState = POWER_OFF;
                LjyLogUtil.i("关机啦~~");
            }
        }

        public void nextChannel() {
            if (mState == POWER_ON) {
                LjyLogUtil.i("下一频道");
            } else {
                LjyLogUtil.i("还没有开机哦");
            }
        }

        public void prevChannel() {
            if (mState == POWER_ON) {
                LjyLogUtil.i("上一频道");
            } else {
                LjyLogUtil.i("还没有开机哦");
            }
        }

        public void turnUp() {
            if (mState == POWER_ON) {
                LjyLogUtil.i("调高音量");
            } else {
                LjyLogUtil.i("还没有开机哦");
            }
        }

        public void turnDown() {
            if (mState == POWER_ON) {
                LjyLogUtil.i("降低音量");
            } else {
                LjyLogUtil.i("还没有开机哦");
            }
        }
    }

那么使用状态模式如何实现呢?

  1. 抽取一个不同状态通用的接口
interface TvState {
        void nextChannel();

        void prevChannel();

        void turnUp();

        void turnDown();
    }
  1. 实现开机关机两种状态
    /**
     * 开机机状态
     */
    class PowerOnState implements TvState {

        @Override
        public void nextChannel() {
            LjyLogUtil.i("下一频道");
        }

        @Override
        public void prevChannel() {
            LjyLogUtil.i("上一频道");
        }

        @Override
        public void turnUp() {
            LjyLogUtil.i("调高音量");
        }

        @Override
        public void turnDown() {
            LjyLogUtil.i("降低音量");
        }
    }

    /**
     * 关机机状态
     */
    class PowerOffState implements TvState {

        @Override
        public void nextChannel() {
            LjyLogUtil.i("还没有开机哦");
        }

        @Override
        public void prevChannel() {
            LjyLogUtil.i("还没有开机哦");
        }

        @Override
        public void turnUp() {
            LjyLogUtil.i("还没有开机哦");
        }

        @Override
        public void turnDown() {
            LjyLogUtil.i("还没有开机哦");
        }
    }

  1. 遥控器类的实现
class TvControler2 {
        //记录状态,默认为关
        private TvState mTvState;

        private void setTvState(TvState tvState) {
            mTvState = tvState;
        }

        public void powerOn() {
            setTvState(new PowerOnState());
            LjyLogUtil.i("开机啦~~");
        }

        public void powerOff() {
            setTvState(new PowerOffState());
            LjyLogUtil.i("关机啦~~");
        }

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

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

        public void turnUp() {
            mTvState.turnUp();
        }

        public void turnDown() {
            mTvState.turnDown();
        }
    }
  1. 创建遥控器类的实例,切换不同的状态
    private void methodStatePattern() {
        LjyLogUtil.i("状态模式:");
        TvControler2 tvControler2 = new TvControler2();

        tvControler2.powerOn();//开机
        tvControler2.nextChannel();
        tvControler2.prevChannel();
        tvControler2.turnUp();
        tvControler2.turnDown();

        tvControler2.powerOff();//关机
        tvControler2.nextChannel();
        tvControler2.prevChannel();
        tvControler2.turnUp();
        tvControler2.turnDown();
    }

虽然看起来更复杂了,但是如果再增加一种状态时,确是要方便很多,不用修改控制器类的现有逻辑,而且状态间的切换也很容易

Android
Web note ad 1