状态模式的定义为:当一个对象的内部状态发生改变时允许改变其行为,这个对象看起来像是改变了其类本身。
状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列当中,可以把复杂的判断逻辑简化。
案例:我们一天的工作状态都是不同的,早上可能精神状态最好,下午可能会犯困,傍晚精神会好转,晚上可能要加班,随着时间的改变而改变。程序实现如下:
第一步:我们不使用状态模式的时候,可能会这样设计程序。
public class Work {
private int hour;
private boolean isFinishWork = false;
public void writeProgram() {
String state = null;
if (hour < 12) {
state = "早上工作状态好";
} else if (hour < 15) {
state = "下午工作犯困";
} else if (hour < 18) {
state = "傍晚工作状态慢慢恢复!";
} else if (hour < 20) {
state = "晚上工作还行";
} else if (isFinishWork) {
state = "工作已经完成,下班";
} else {
if (hour < 22) {
state = "太累了,快睡着了";
} else {
state = "睡着了~~~";
}
}
System.out.println(state);
}
<span style="white-space:pre"> </span>public int getHour() {
return hour;
}
public void setHour(int hour) {
this.hour = hour;
}
public boolean isFinishWork() {
return isFinishWork;
}
public void setFinishWork(boolean isFinishWork) {
this.isFinishWork = isFinishWork;
}
}
第二步:测试类如下:
public class Test1 {
public static void main(String[] args) {
Work work = new Work();
work.setHour(10);
work.writeProgram();
work.setHour(14);
work.writeProgram();
work.setHour(17);
work.writeProgram();
work.setHour(21);
work.writeProgram();
work.setFinishWork(true);
//work.setFinishWork(false);
work.setHour(23);
work.writeProgram();
}
}
第三步:我们来分析一下,我们的Work类中的writeProgram()方法需要根据运行时的hour状态来判断,进而作出不同的行为反应,但是这个类的职责过重,需要进行多次判断,条件判断语句也过多,当需求改变的时候该类肯定会被修改以实现需求。我们使用状态模式来实现,先把与hour状态相关的行为抽象出来,这里用接口实现,然后在子类中实现具体的行为,这里定义五个不同的状态表示。
public interface State {
public void writeProgram(Work work);
}
public class WorkStateToMooning implements State {
public void writeProgram(Work work) {
String state = null;
if (work.getHour() < 12) {
state = "早上工作状态好";
System.out.println(state);
} else {
work.setState(new WorkStateToAfternoon());
work.writeProgram();
}
}
}
public class WorkStateToAfternoon implements State {
public void writeProgram(Work work) {
String state = null;
if (work.getHour() < 15) {
state = "下午犯困~~";
System.out.println(state);
} else {
work.setState(new WorkStateToDiner());
work.writeProgram();
}
}
}
public class WorkStateToDiner implements State {
public void writeProgram(Work work) {
String state = null;
if (work.getHour() < 18) {
state = "傍晚慢慢恢复精神状态!";
System.out.println(state);
} else {
work.setState(new WorkStateToNight());
work.writeProgram();
}
}
}
public class WorkStateToNight implements State {
public void writeProgram(Work work) {
String state = null;
if (work.getHour() < 22) {
state = "好累,想要休息~~";
System.out.println(state);
} else if (work.isFinishWork()) {
work.setState(new WorkStateToFinish());
work.writeProgram();
}
}
}
public class WorkStateToFinish implements State {
public void writeProgram(Work work) {
String state = null;
state = "工作已经完成,哈哈!";
System.out.println(state);
}
}
第四步:测试类不变,运行结果如下:
早上工作状态好
下午犯困~~
傍晚慢慢恢复精神状态!
好累,想要休息~~
工作已经完成,哈哈!
总结:状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列对象当中,可以把复杂的判断逻辑简化。状态模式的好处是:将与特定状态相关的行为局部化,并且将不同状态的行为分隔开来。
应用场景:当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时就可以考虑使用状态模式。