状态模式
定义
当一个对象的内在状态改变时允许改变其行为,这个对象看起来是改变了其类。
UML
代码需求分许过程
需求:根据每个时间段员工的不同状态写出相关的表示员工状态的类
工作状态-函数版(完成基本的功能)
public class Demo { static int hour=0; static boolean workFinished=false; public static void main(String[] args) { if (hour<12){ System.out.println("上午工作,精力十分好"); } else if (hour<13){ System.out.println("午睡时间,不能工作了..."); } else if (hour<17){ System.out.println("下午了,状态好,继续工作..."); } else { if (workFinished){ System.out.println("工作完成,下班回家"); } else if(hour<21){ System.out.println("加班啦,贼累"); } else { System.out.println("睡觉了,不搞了,不搞了"); } } } }
分析:这个函数出现的问题:能够完成基本的功能。但是,这个实际上是面向过程开发的,不是面向对象来操作的。
工作状态-面向对象
public class Demo2 { private int hour; private boolean finish=false; 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(){ if (hour<12){ System.out.println("上午工作,精力十分好"); } else if (hour<13){ System.out.println("午睡时间,不能工作了..."); } else if (hour<17){ System.out.println("下午了,状态好,继续工作..."); } else { if (finish){ System.out.println("工作完成,下班回家"); } else if(hour<21){ System.out.println("加班啦,贼累"); } else { System.out.println("睡觉了,不搞了,不搞了"); } } } } class Client{ public static void main(String[] args) { Demo2 demo2=new Demo2(); demo2.setHour(9); demo2.writeProgram(); } }
说明:程序代码不宜过长,过长的代码是一个坏的事情。因为过长的代码会导致某个类的责任过于重大,所以我们需要尽量做到将代码的责任分解。
因为时间的改变会导致状态的改变,那么这种设计思维是符合状态模式的,接下来使用状态模式进行改造:
public abstract class BaseState { /** * 描述状态的改变 * @param work :设置工作的状态 * */ public abstract void handle(Work work); }
public class ForenoonState extends BaseState { @Override public void handle(Work work) { if (work.getHour()<12){ System.out.println("上午工作,精力十分好"); } //超过了上午的时间,那么就是转入中午这个时间段 else { work.setCurrentState(new NoonState()); work.writeProgram(); } } }
public class NoonState extends BaseState { @Override public void handle(Work work) { if (work.getHour()<13){ System.out.println("午睡时间,不能工作了..."); } else { work.setCurrentState(new AfternoonState()); work.writeProgram(); } } }
public class AfternoonState extends BaseState { @Override public void handle(Work work) { if (work.getHour()<17){ System.out.println("下午了,状态好,继续工作..."); } else { work.setCurrentState(new EveningState()); work.writeProgram(); } } }
public class EveningState extends BaseState { @Override public void handle(Work work) { if (work.isFinish()){ System.out.println("任务完成,下班回家,开心ing..."); } else { if (work.getHour()<21){ System.out.println("加班啦,贼累"); } else { System.out.println("睡觉了,不搞了,不搞了"); } } } }
public class Work { private BaseState currentState; /** * 设定初始的工作状态 * */ public Work() { currentState=new ForenoonState(); } private double hour; public double getHour() { return hour; } public void setHour(double hour) { this.hour = hour; } private boolean finish=false; public boolean isFinish() { return finish; } public void setFinish(boolean finish) { this.finish = finish; } public void setCurrentState(BaseState currentState) { this.currentState = currentState; } public void writeProgram(){ currentState.handle(this); } }
public class Client { public static void main(String[] args) { Work work=new Work(); work.setHour(9); work.writeProgram(); work.setHour(22); work.writeProgram(); } }
说明:采用了状态模式(state),将多个判断切分开来,避免一个work类里面有太多的分支。符合单一职责原则
小结
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。当一个对象的欣慰取决于它的状态,并且它必须在运行时刻根据状态改变行为的时候,那么这个时候就考虑使用状态模式。