状态模式
工作时,上午状态好,中午想睡觉,加班苦煎熬;其实这是一种状态的变化,不同的时间,会有不同的状态.
原始代码
public class Work1 {
private int hour;
private boolean finish=false;
public boolean isFinish() {
return finish;
}
public void setFinish(boolean finish) {
this.finish = finish;
}
public int getHour() {
return hour;
}
public void setHour(int hour) {
this.hour = hour;
}
public void writeProgram() {
if(hour<12) {
System.out.println("当前时间"+hour+"上午工作,精神百倍");
}else if(hour<13) {
System.out.println("当前时间"+hour+"吃饭午休,又饿又困");
}else if(hour<17) {
System.out.println("当前时间"+hour+"下午状态不错");
}else {
if(finish) {
System.out.println("当前时间"+hour+"下班回家");
}else {
if(hour<21) {
System.out.println("当前时间"+hour+"还在加班,好累");
}else {
System.out.println("当前时间"+hour+"已猝死");
}
}
}
}
}
工作类中的writeProgram类的方法太长了,包含了太多的判断(责任过大),任何需求的改动和增加都需要改动这个方法;然而面向对象设计其实就是希望做到代码的责任分解,工作类违背了单一职责原则和开放封闭原则,维护时比较困难,而且容易出错.
状态模式
当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类.它主要解决的是当控制一个对象状态转换的条件表达式过于复杂的情况.把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简单化.当然,如果这个状态判断很简单,就没有必要用状态模式了.
public abstract class State {
public abstract void writeProgram(Work2 w);
}
public class MorningState extends State{
public void writeProgram(Work2 w) {
if(w.getHour()<12) {
System.out.println("当前时间"+w.getHour()+"上午工作,精神百倍");
}else {
//超过12点,则进入中午工作状态
w.setState(new NoonState());
w.writeProgram();
}
}
}
public class NoonState extends State {
public void writeProgram(Work2 w) {
if(w.getHour()<13) {
System.out.println("当前时间"+w.getHour()+"吃饭午休,又饿又困");
}
}
}
public class Work2 {
private State state;
//通过构造器,定义工作的初始状态
public Work2(State state) {
this.state=state;
}
private int hour;
private boolean finish=false;
//用于读取当前状态或者设置新状态
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 isFinish() {
return finish;
}
public void setFinish(boolean finish) {
this.finish = finish;
}
public void writeProgram() {
//其子类对请求做处理,并设置一下状态
state.writeProgram(this);
}
}
状态模式的好处:
将与特定状态相关的行为局部化,并且将不同状态的行为分割开来.将特定状态相关的行为放在一个类中,通过增加新的类可以很容易的实现新的状态和转换.说白了,这样做的目的可以消除庞大的条件分支语句,状态模式通过把各种状态转移逻辑分布到state和子类之间,来减少相互的依赖.
何时使用状态模式?
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式.另外如果业务需求某项业务有多个状态,状态的变化都是依靠大量的分支判断语句来实现,此时应该考虑为每一种业务状态定义为一个State的子类.