前言
状态模式顾名思义,它是依据状态的不同,调用同样的方法却有不同的行为。每一个状态都有一个共同的状态基类,状态模式的目的就是在状态改变的时候,行为也跟着改变。
多用于一个对象的行为取决于它的状态,且必须在运行时根据状态改变它的行为。或者一个对象中有大量的操作判断比如if else switch,且依赖于该对象的状态。
状态模式定义
依据状态的不同,调用同样的方法却有不同的行为
状态模式举例
我们举一个车辆限行的例子:
重庆嘉华大桥最近实行限号措施,星期一限行尾数1和6、星期二限行尾数2和7,这里为了省略篇幅,我们只写周一周二两种状态
先抽象出一个接口方法,判断是否限行
public interface Check {
boolean limit(int lastNumber);
}
然后定义周一和周二两种不同状态同个limit方法下,不同的处理行为。
public class Monday implements Check {
@Override
public boolean limit(int lastNumber) {
if (lastNumber == 1 || lastNumber == 6) {
return true;
}
return false;
}
}
public class Tuesday implements Check {
@Override
public boolean limit(int lastNumber) {
if (lastNumber == 2 || lastNumber == 7) {
return true;
}
return false;
}
}
最后定义一个判断限行的类,来统一管理和处理
public class LimitLine {
private Check check;
public void setCheck(Check check) {
this.check = check;
}
public boolean getLimitLine (int lastNumber) {
return check.limit(lastNumber);378915406@qq.com
}
}
到此,状态模式就写完了,然后我们看一下怎么调用它
Monday monday = new Monday();
Tuesday tuesday = new Tuesday();
LimitLine limitLine = new LimitLine();
limitLine.setCheck(monday);
boolean mondayLimitOne = limitLine.getLimitLine(1);
boolean mondayLimitTwo = limitLine.getLimitLine(2);
limitLine.setCheck(tuesday);
boolean tuesdayLimitOne = limitLine.getLimitLine(1);
boolean tuesdayLimitTwo = limitLine.getLimitLine(2);
Log.d("State","mondayLimitOne = " + mondayLimitOne);
Log.d("State","mondayLimitTwo = " + mondayLimitTwo);
Log.d("State","tuesdayLimitOne = " + tuesdayLimitOne);
Log.d("State","tuesdayLimitTwo = " + tuesdayLimitTwo);
LOG输出如下:
D/State: mondayLimitOne = true
D/State: mondayLimitTwo = false
D/State: tuesdayLimitOne = false
D/State: tuesdayLimitTwo = true
状态模式小结
现在来整体看下代码,状态模式结构很简单,根据不同的状态,使用同种方法(接口),通过子类去实现不同的行为。对与这里的例子就是,根据星期几的不同,去判断限行。方法是判断限行,但是因为2018-11-10星期几这个状态的不同,相同的尾号条件,相同的判断方法,得到不同的结果。
最后说下状态模式和策略模式的区别,虽然他们在代码结构上几乎相同,但思想确实不同的,最最最最最根本的区别点在于:
1、策略模式的侧重点是提供不同的方法(策略)。
2、状态模式的行为是由状态来决定,不同状态有不同的行为。
One more thing! 有的人或许会认为策略模式和状态模式就是一种模式,但不是这样。假设我们现在对一个数组从小到大排序,这个时候我们写了两个策略,一个冒泡排序,一个插入排序。两个策略。结果都能正常排序。所以策略模式的重点是不同的策略上。状态模式就是本文所讲,重点在状态上。
结束语
状态模式的应用场景也很明显,就是根据状态的不同,同种方法需要不同的行为。如果不用状态模式,你可以写if else 或者 switch语句,但是这样会很臃肿,且不好扩展,比如本文的例子,你需要判断周一到周天七个状态,这里的方法的代码简单还好,如果很复杂。你的代码就会显得很臃肿。耦合度高,增加了出错率。用状态模式则能很好的避免,且代码结构简单清晰。