状态模式(State),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列当中,可以把复杂的判断逻辑简化。当然,如果这个状态判断很简单,那就没必要使用“状态模式”了。
举例:
在公司工作工作一天,每个阶段的工作状态都不同,比如上午会比较精神,中午困了需要休息,下午休息完后又有精神了,但是到了晚上如果加班很晚,就会很累,加班到凌晨可能就会在单位休息了。由于判断比较多,就可以用状态模式来实现。
- 工作类
public class Work {
// 时间
private int hour;
// 相应时间的工作状态
private State state;
// 工作是否完成标识
private boolean workFinished = false;
public Work() {
hour = 8;
state = new MorningWorkState();
}
public void getWorkState(){
state.workState(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 isWorkFinished() {
return workFinished;
}
public void setWorkFinished(boolean workFinished) {
this.workFinished = workFinished;
}
}
- 工作状态抽象类
public abstract class State {
public abstract void workState(Work work);
}
- 工作状态子类
// 早上
public class MorningWorkState extends State {
@Override
public void workState(Work work) {
if (work.getHour() < 12) {
System.out.println("当前时间:" + work.getHour() + "点, 上午工作,精神百倍");
} else {
work.setState(new NoonWorkState());
work.getWorkState();
}
}
}
// 中午
public class NoonWorkState extends State {
@Override
public void workState(Work work) {
if (work.getHour() < 13) {
System.out.println("当前时间:" + work.getHour() + "点, 饿了,午饭;犯困,午休");
} else {
work.setState(new AfternoonWorkState());
work.getWorkState();
}
}
}
// 下午
public class AfternoonWorkState extends State {
@Override
public void workState(Work work) {
if (work.getHour() < 17) {
System.out.println("当前时间:" + work.getHour() + "点, 下午状态还不错,继续努力");
} else {
work.setState(new EveningWorkState());
work.getWorkState();
}
}
}
// 晚上
public class EveningWorkState extends State {
@Override
public void workState(Work work) {
if (work.isWorkFinished()) {
System.out.println("当前时间:" + work.getHour() + "点, 工作已完成,准备回家");
work.setState(new RestWorkState());
work.getWorkState();
} else {
if (work.getHour() < 21) {
System.out.println("当前时间:" + work.getHour() + "点, 加班哦,疲惫至极");
} else {
work.setState(new NightWorkState());
work.getWorkState();
}
}
}
}
// 夜晚
public class NightWorkState extends State {
@Override
public void workState(Work work) {
System.out.println("当前时间:" + work.getHour() + "点,不行了,睡着了");
}
}
// 工作完,休息
public class RestWorkState extends State {
@Override
public void workState(Work work) {
System.out.println("当前时间:" + work.getHour() + "点, 准备休息了");
}
}
- 主程序
public class Test {
public static void main(String[] args) {
Work work = new Work();
work.setHour(8);
work.getWorkState();
work.setHour(10);
work.getWorkState();
work.setHour(12);
work.getWorkState();
work.setHour(13);
work.getWorkState();
work.setHour(14);
work.getWorkState();
work.setHour(17);
work.getWorkState();
work.setHour(19);
work.getWorkState();
work.setWorkFinished(true);
work.setHour(22);
work.getWorkState();
}
}
运行结果
当前时间:8点, 上午工作,精神百倍
当前时间:10点, 上午工作,精神百倍
当前时间:12点, 饿了,午饭;犯困,午休
当前时间:13点, 下午状态还不错,继续努力
当前时间:14点, 下午状态还不错,继续努力
当前时间:17点, 加班哦,疲惫至极
当前时间:19点, 加班哦,疲惫至极
当前时间:22点, 工作已完成,准备回家
当前时间:22点, 准备休息了
当把work.setWorkFinished(true);
注释掉时,最后的结果为当前时间:22点,不行了,睡着了