适用场合:控制一个对象的状态转换的条件表达试过于复杂时,有可能出现过多的if else语句,此时可以把状态的判断逻辑移到一系列表示不同状态的类中,此时可以简化状态的判断逻辑,而且需要增加判断逻辑时,只需要增加一个状态类就可以了,如果需要修改也只需要修改相应的状态类就可以了,而不会违背面向对象的设计原则之一:开放-封闭原则。
那么状态模式的好处是什么呢?其实从上面的分析我们已经知道了,那就是它可以将与特定状态相关的行为局部化,并且将不同状态的行为分割开来;所以当一个对象的行为取决于它的状态,且它必须在运行时刻根据状态改变它的行为时就可以考虑使用状态模式了。
下面是状态模式的典型代码结构:
1 接口State.java
package com.ops.state;
public interface State {
public void writeProgram(Work work);
}
2 上下文Work.java
package com.ops.state;
public class Work {
private int hour = -1;
private boolean isFinished = false;
private State currentState = null;
public Work(State state) {
this.currentState = state;
}
public int getHour() {
return hour;
}
public void setHour(int hour) {
this.hour = hour;
}
public boolean isFinished() {
return isFinished;
}
public void setFinished(boolean isFinished) {
this.isFinished = isFinished;
}
public State getCurrentState() {
return currentState;
}
public void setCurrentState(State currentState) {
this.currentState = currentState;
}
public void writeProgram() {
this.currentState.writeProgram(this);
}
}
3 接口State.java的实现类,这里有六个.java文件,都是实现类
3.1 ForenoonState.java
package com.ops.state.base;
import com.ops.state.State;
import com.ops.state.Work;
public class ForenoonState implements State {
@Override
public void writeProgram(Work work) {
if (12 > work.getHour()) {
System.out.printf("当前时间:%d点,上午工作就是精神百倍啊!\n", work.getHour());
} else {
work.setCurrentState(new NoonState());
work.writeProgram();
}
}
}
3.2 NoonState.java
package com.ops.state.base;
import com.ops.state.State;
import com.ops.state.Work;
public class NoonState implements State {
@Override
public void writeProgram(Work work) {
if (13 > work.getHour()) {
System.out.printf("当前时间:%d点,有点饿了,午饭时间到;犯困了要休息了!\n", work.getHour());
} else {
work.setCurrentState(new AfternoonState());
work.writeProgram();
}
}
}
3.3 AfternoonState.java
package com.ops.state.base;
import com.ops.state.State;
import com.ops.state.Work;
public class AfternoonState implements State{
@Override
public void writeProgram(Work work) {
if (17 > work.getHour()) {
System.out.printf("当前时间:%d点,下午状态还不错,继续努力啊!\n", work.getHour());
} else {
work.setCurrentState(new EveningState());
work.writeProgram();
}
}
}
3.4 EveningState.java
package com.ops.state.base;
import com.ops.state.State;
import com.ops.state.Work;
public class EveningState implements State {
@Override
public void writeProgram(Work work) {
if (work.isFinished()) {
work.setCurrentState(new RestState());
work.writeProgram();
} else {
if (21 > work.getHour()) {
System.out.printf("当时时间:%d点,加班时间了,好累啊!\n", work.getHour());
} else {
work.setCurrentState(new SleepingState());
work.writeProgram();
}
}
}
}
3.5 RestState.java
package com.ops.state.base;
import com.ops.state.State;
import com.ops.state.Work;
public class RestState implements State {
@Override
public void writeProgram(Work work) {
System.out.printf("当前时间:%d点,工作完成,下班回家了,哈哈!\n", work.getHour());
}
}
3.6 SleepingState.java
package com.ops.state.base;
import com.ops.state.State;
import com.ops.state.Work;
public class SleepingState implements State {
@Override
public void writeProgram(Work work) {
System.out.printf("当前时间:%d点,不行了,已经睡着了!\n", work.getHour());
}
}
4 下面是客户端组装代码StateClient.java:
package com.ops.state.main;
import org.junit.Test;
import com.ops.state.Work;
import com.ops.state.base.ForenoonState;
public class StateClient {
@Test
public void test() {
Work work = new Work(new ForenoonState());
//早上的状态
work.setHour(9);
work.writeProgram();
work.setHour(10);
work.writeProgram();
//中等的状态
work.setHour(12);
work.writeProgram();
//下午的状态
work.setHour(14);
work.writeProgram();
work.setHour(17);
//work.setFinished(true);
work.writeProgram();
work.setHour(19);
work.writeProgram();
work.setHour(21);
work.writeProgram();
}
}