概述
状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了它的类一样。
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一组类中,可以把复杂的判断逻辑简化。
状态模式的结构
用一句话来表述,状态模式把所研究的对象的行为包装在不同的状态对象里,每一个状态对象都属于一个抽象状态类的一个子类。状态模式的意图是让一个对象在其内部状态改变的时候,其行为也随之改变。状态模式的示意性类图如下所示:
状态模式所涉及到的角色:
环境(Context)角色,上下文:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态。
在状态模式中,环境(Context)是持有状态的对象,但是环境(Context)自身并不处理跟状态相关的行为,而是把处理状态的功能委托给了状态对应的状态处理类来处理。
在具体的状态处理类中经常需要获取环境(Context)自身的数据,甚至在必要的时候会回调环境(Context)的方法,因此,通常将环境(Context)自身当作一个参数传递给具体的状态处理类。
客户端一般只和环境(Context)交互。客户端可以用状态对象来配置一个环境(Context),一旦配置完毕,就不再需要和状态对象打交道了。客户端通常不负责运行期间状态的维护,也不负责决定后续到底使用哪一个具体的状态处理对象。
抽象状态(State)角色:定义一个接口,用以封装环境(Context)对象的一个特定的状态所对应的行为。
具体状态(ConcreteState)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。
源代码
/**
* 工作状态的接口
*/
public interface State {
/**
* 工作的方法
* @param work
*/
public void doJob(Work work);
}
/**
* 早上的工作状态
*/
public class MorningState implements State {
@Override
public void doJob(Work work) {
if(work.getHour() < 12){
System.out.println("当前时间:" + work.getHour() + ",上午在写代码");
}else{
//超过12点转入中午状态
work.setState(new NoonState());
work.doJob();
}
}
}
/**
* 中午的工作状态
*/
public class NoonState implements State {
@Override
public void doJob(Work work) {
if(work.getHour() < 14){
System.out.println("当前时间:" + work.getHour() + ",中午在午休");
}else{
//超过14点转入下午状态
work.setState(new AfternoonState());
work.doJob();
}
}
}
/**
* 下午的工作状态
*/
public class AfternoonState implements State {
@Override
public void doJob(Work work) {
if(work.getHour() < 18){
System.out.println("当前时间:" + work.getHour() + ",下午上班");
}else{
//若超过18点并且完成工作则进入休息状态,否则进入加班状态
if(work.isFinishWork()){
work.setState(new RestState());
work.doJob();
}else{
work.setState(new OvertimeState());
work.doJob();
}
}
}
}
/**
* 加班的工作状态
*/
public class OvertimeState implements State {
@Override
public void doJob(Work work) {
if(work.getHour() < 21){
System.out.println("当前时间:" + work.getHour() + ",加班中");
}else{
//21点强制下班
work.setState(new RestState());
work.doJob();
}
}
}
/**
* 休息的状态
*/
public class RestState implements State {
@Override
public void doJob(Work work) {
System.out.println("当前时间:" + work.getHour() + ",休息");
}
}
/**
* 工作类,包含了State状态的引用,实际就是标准结构中的环境类Context
*/
public class Work {
//状态
private State state;
//是否完成工作,若完成可以由下午工作状态或加班工作状态转入休息工作状态
private boolean finishWork;
//工作的当前时间,小时
private int hour;
public Work(){
//默认初始化早上的工作状态
finishWork = false;
hour = 9;
state = new MorningState();
}
/**
* 这里相当于代理,调用传入进来的工作状态State的doJob方法,把本身的实例作为参数传入
*/
public void doJob(){
state.doJob(this);
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public boolean isFinishWork() {
return finishWork;
}
public void setFinishWork(boolean finishWork) {
this.finishWork = finishWork;
}
public int getHour() {
return hour;
}
public void setHour(int hour) {
this.hour = hour;
}
}
/**
* 客户端
*/
public class Client {
public static void main(String[] args) {
Work work = new Work();
work.doJob();
work.setHour(11);
work.doJob();
work.setHour(12);
work.doJob();
work.setHour(13);
work.doJob();
work.setHour(14);
work.doJob();
work.setHour(16);
work.doJob();
work.setFinishWork(true);
work.setHour(18);
work.doJob();
work.setHour(19);
work.doJob();
work.setHour(20);
work.doJob();
work.setHour(22);
work.doJob();
}
}
网友评论