这里是引用
状态模式中的行为是由状态决定的,不同的状态下有不同的行为。状态模式和策略模式的结构几乎完全一样,但它们的目的,本质却完全不一样。状态模式的行为是平行的,不可替换的,策略模式的行为是彼此独立,可相互替换的。用一句话来说,状态模式把对象的行为包装在不同状态对象里,每一个状态对象都有一个共同的抽象基类。状态模式的意图是让一个对象在其内部状态改变的时候,其行为也随之改变。
当一个对象的内在状态发生改变时允许改变其行为,这个对象看起来像是改变了其类。
1.一个对象的行为取决与它的状态,并且它必须运行时根据状态改变它的行为。
2.代码中包含大量与状态有关的条件语句。
以遥控器为例演示状态模式的实现。遥控器有开机,关机两种状态,通过遥控器可以频道切换,音量调整。但关机状态时不能操作的。
public class TvController { private static final String TAG = "TvController"; //开机状态 private final static int POWER_ON = 1; //关机状态 private final static int POWER_OFF = 2; //当前状态 private int mState = POWER_OFF; public void powerOn() { if (mState == POWER_OFF) { mState = POWER_ON; Log.d(TAG, "powerOn: 开机了"); } } public void powerOff() { if (mState == POWER_ON) { mState = POWER_OFF; Log.d(TAG, "powerOff: 关机了"); } } public void nextChannel() { if (mState == POWER_ON) { Log.d(TAG, "nextChannel: 下一频道"); } else { Log.d(TAG, "nextChannel: 没有开机"); } } public void prevChannel() { if (mState == POWER_ON) { Log.d(TAG, "prevChannel: 上一频道"); } else { Log.d(TAG, "prevChannel: 没有开机"); } } public void turnUp() { if (mState == POWER_ON) { Log.d(TAG, "prevChannel: 调高音量"); } else { Log.d(TAG, "prevChannel: 没有开机"); } } public void turnDown() { if (mState == POWER_ON) { Log.d(TAG, "prevChannel: 调低音量"); } else { Log.d(TAG, "prevChannel: 没有开机"); } } }
这么写导致每个功能都需要条件判断,代码重复如果功能变多了,会变得越来越难维护。
状态模式就是为了解决这类问题。
调整:
public interface TvState { void nextChannel(); void prevChannel(); void turnUp(); void turnDown(); }
public class PowerOffState implements TvState { @Override public void nextChannel() { } @Override public void prevChannel() { } @Override public void turnUp() { } @Override public void turnDown() { } }
public class PowerOnState implements TvState { private static final String TAG = "PowerOnState"; @Override public void nextChannel() { Log.d(TAG, "nextChannel: 下一频道"); } @Override public void prevChannel() { Log.d(TAG, "prevChannel: 上一频道"); } @Override public void turnUp() { Log.d(TAG, "turnUp: 调高音量"); } @Override public void turnDown() { Log.d(TAG, "turnDown: 调低音量"); } }
public interface PowerController { void powerOn(); void powerOff(); }
public class TvController implements PowerController { private static final String TAG = "TvController"; private TvState tvState; private void setTvState(TvState tvState) { this.tvState = tvState; } @Override public void powerOn() { setTvState(new PowerOnState()); Log.d(TAG, "powerOn: 开机了"); } @Override public void powerOff() { setTvState(new PowerOffState()); Log.d(TAG, "powerOff: 关机了"); } public void nextChannel() { tvState.nextChannel(); } public void prevChannel() { tvState.prevChannel(); } public void turnUp() { tvState.turnUp(); } public void turnDown() { tvState.turnDown(); } }
TvController tvController = new TvController(); tvController.powerOn(); tvController.nextChannel(); tvController.turnDown(); tvController.powerOff();
优点:
状态模式将所有与一个特定的状态相关的行为都放在一个状态对象中,它提供了一个更好的方法来组织与特定状态相关的代码,将繁琐的状态判断转换成结构清晰的状态类,在避免代码膨胀的同时也保障了可扩展性与可维护性。
缺点:
状态模式的使用必然会增加系统类和对象的个数。