状态模式是当一个对象的内在状态改变的时候,允许改变其行为。这个对象看起来像是改变了它的类。
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时,将状态的判断逻辑转移到表示不同状态的一系列类中。可以简化判断逻辑。
假设我们要模拟一个上班工作的过程,工作有不同状态,比如上午,中午,下午,晚上,下班等。而这些状态不同,我们工作的行为也会不同。这个时候我们就可以利用状态模式来模拟这个过程。
首先我们要有一个抽象的状态类
public abstract class State {
public abstract void writeProgram(work w);
}
这个状态类有一个writeProgram方法,来模拟我们工作时的行为,同时传入一个Work对象,work对象封装了一些比如当前时间、工作是否已完成等参数。
然后我们要有几个具体的状态类
public class MorningState extends State {
@Override
public void writeProgram(Work w) {
if(12 > w.getHour()) {
System.out.println(w.getHour() + "点,早上工作,有精神");
} else {
w.setState(new NoonState());
w.writeProgram();
}
}
}
public class NoonState extends State {
@Override
public void writeProgram(Work w) {
if(13 > w.getHour()) {
System.out.println(w.getHour() + "点,中午工作,犯困");
} else {
w.setState(new AfternoonState());
w.writeProgram();
}
}
}
public class AfternoonState extends State {
@Override
public void writeProgram(Work w) {
if(17 > w.getHour()) {
System.out.println(w.getHour() + "点,下午工作,感觉海星~");
} else {
w.setState(new NightState());
w.writeProgram();
}
}
}
public class NightState extends State {
@Override
public void writeProgram(Work w) {
if(w.isTaskFinish()) {
w.setState(new RestState());
w.writeProgram();
} else {
if(21 > w.getHour()) {
System.out.println(w.getHour() + "点,晚上工作,犯困");
} else {
w.setState(new SleepingState());
w.writeProgram();
}
}
}
}
public class SleepingState extends State {
@Override
public void writeProgram(Work w) {
System.out.println(w.getHour() + "点,顶不住睡着了!");
}
}
public class RestState extends State {
@Override
public void writeProgram(Work w) {
System.out.println(w.getHour() + "点,下班了,不工作了!");
}
}
可以看到,在具体的状态中,我们会根据时间和工作完成状态,来判断是否满足当前状态。若不满足,则会将状态设置为下一个状态,然后调用行为方法。然后在下一个状态的行为方法中,又会判断是否满足当前状态,这样就形成了一个行为的流转,我们把统一的复杂行为判断,转移到了各个状态中,减少了逻辑判断的复杂度。
然后我们需要一个Work类
public class Work {
private State state;
private int hour;
private boolean taskFinish;
public Work() {
//初始状态为早晨
this.state = new MorningState();
}
public void writeProgram() {
state.writeProgram(this);
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public int getHour() {
return hour;
}
public void setHour(int hour) {
this.hour = hour;
}
public boolean isTaskFinish() {
return taskFinish;
}
public void setTaskFinish(boolean taskFinish) {
this.taskFinish = taskFinish;
}
}
可以看到,这个时候的work类,没有了对条件的复杂判断,只需要给定一个初始状态,然后把判断交给各个状态自身即可。
相关demo可以参考我的gitee仓库
https://gitee.com/akitsuki-kouzou/DesignPatternDemo