Android设计模式-7-状态模式
2018-06-05 本文已影响155人
今阳说
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("还没有开机哦");
}
}
}
那么使用状态模式如何实现呢?
- 抽取一个不同状态通用的接口
interface TvState {
void nextChannel();
void prevChannel();
void turnUp();
void turnDown();
}
- 实现开机关机两种状态
/**
* 开机机状态
*/
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("还没有开机哦");
}
}
- 遥控器类的实现
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();
}
}
- 创建遥控器类的实例,切换不同的状态
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();
}
虽然看起来更复杂了,但是如果再增加一种状态时,确是要方便很多,不用修改控制器类的现有逻辑,而且状态间的切换也很容易