一,定义
状态模式:当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。
状态模式主要解决的是当控制一个对象状态转换条件表达式过于复杂时的情况,把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
二,示例
实现一个根据时间变化,工作状态发生变化的示例
public abstract class State {
//根据不同的工作时间,展示不同的工作状态
public abstract void workStatus(Work wrok);
}
public class ForenoonState extends State {
@Override
public void workStatus(Work wrok) {
if (wrok.getHour() < 12){
System.out.println("当前时间:" + wrok.getHour() + "点,上午工作,精神百倍!");
} else {
wrok.setCurrent(new NoonState());
wrok.working();
}
}
}
public class NoonState extends State {
@Override
public void workStatus(Work wrok) {
if (wrok.getHour() < 13){
System.out.println("当前时间:" + wrok.getHour() + "点,饿了,午饭,犯困...,午休!");
} else {
wrok.setCurrent(new AfternoonState());
wrok.working();
}
}
}
public class AfternoonState extends State {
@Override
public void workStatus(Work wrok) {
if (wrok.getHour() < 17){
System.out.println("当前时间:" + wrok.getHour() + "点,下午状态还不错,继续努力!");
} else {
wrok.setCurrent(new EveningState());
wrok.working();
}
}
}
public class Work {
private double hour;
private State current;
private boolean isFinish;
public Work(){
current = new ForenoonState();
}
public void working(){
current.workStatus(this);
}
public double getHour() {
return hour;
}
public void setHour(double hour) {
this.hour = hour;
}
public State getCurrent() {
return current;
}
public void setCurrent(State current) {
this.current = current;
}
public boolean isFinish() {
return isFinish;
}
public void setFinish(boolean finish) {
isFinish = finish;
}
}
//test main
//状态模式
public static void stateModel(){
Work work = new Work();
work.setHour(9);
work.working();
work.setHour(10);
work.working();
work.setHour(12);
work.working();
work.setHour(13);
work.working();
work.setHour(14);
work.working();
work.setHour(17);
work.setFinish(false);
work.working();
work.setHour(19);
// work.setFinish(true);
work.working();
work.setHour(22);
work.working();
}
输出结果:
当前时间:9.0点,上午工作,精神百倍!
当前时间:10.0点,上午工作,精神百倍!
当前时间:12.0点,饿了,午饭,犯困…,午休!
当前时间:13.0点,下午状态还不错,继续努力!
当前时间:14.0点,下午状态还不错,继续努力!
当前时间:17.0点,加班哦,疲惫至极!
当前时间:19.0点,加班哦,疲惫至极!
当前时间:22.0点,不行了,睡着了!
三,总结
优点:
1,将与特定状态相关的行为局部化,并且将不同状态行为分割开来。说白了就是将特定的状态的行为都放入一个对象中,由于所有与状态相关的代码都存于某个具体State中,所以通过定义新的子类可以很容易地增加新的状态和转换。
2,通过把各种状态转移逻辑分不到State的子类之间,来减少相互之间的依赖。
使用场景:
1,当一个对象的行为取决于它的状态,并且它必须在运行时,时刻根据状态改变他的行为,就可以考虑使用状态模式。
2,另外如果业务需求某项业务有多个状态,通常是使用枚举,状态的变化都是依靠大量的分支判断语句来实现的,此时应该考虑将每一个业务分支状态定义为一个State子类,这样这些对象就可以不依赖于其他对象而独立变化了。某一天客户需要改变需求,增加和减少业务状态或改变状态流程,对你来说都不是难事。
参考:《大话设计模式》