状态模式:当一个对象的内在状态改变时允许其改变行为,这个对象看起来像是改变了其类。
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
状态模式的好处是将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个ConcreteState中,所以通过定义新的子类可以很容易地增加新的状态和转换。
这样做的目的就是消除庞大的条件分支语句,大的分支判断会使得他们难以修改和扩展。状体模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖。
应用场景:当一个对象的行为取决于它的状态,并且他必须在运行的时候 时刻根据状态 改变他的行为时,就可以考虑使用状态模式了。
不同状态下做不同的行为!!!
1 //State类,抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为。 2 public abstract class State { 3 //定义一个抽象方法来执行相关的行为 4 public abstract void handle(Context context); 5 }
1 /** 2 * Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态。 3 * @author 贤元 4 * 5 */ 6 public class Context { 7 //状态 8 private State state; 9 public Context(State state){//定义Context的初始状态 10 this.state = state; 11 } 12 13 //对请求做处理,并设置状态。状态改变之后要做的事情。 14 public void request(){ 15 state.handle(this); 16 } 17 18 19 //可读可写的状态属性,用于读取当前状态和设置新状态 20 public State getState() { 21 return state; 22 } 23 24 public void setState(State state) { 25 this.state = state; 26 } 27 }
1 /** 2 * ConcreteStateA类,具体状态,每一个子类实现一个与Context的一个状态相关的行为。 3 * @author 贤元 4 * 5 */ 6 public class ConcreteStateA extends State{ 7 8 @Override 9 public void handle(Context context) { 10 // 设置ConcreteStateA下的一状态是ConcreteStateB 11 context.setState(new ConcreteStateB());//切换状态 12 System.out.println("状态A时要做的事。"); 13 } 14 15 }
1 //ConcreteStateB具体状态,每一个子类实现一个与Context的一个状态相关的行为。 2 public class ConcreteStateB extends State { 3 4 @Override 5 public void handle(Context context) { 6 // 设置ConcreteStateB下的一状态是ConcreteStateA 7 context.setState(new ConcreteStateA());//切换状态 8 System.out.println("状态B时要做的事"); 9 } 10 11 }
测试类:
1 public class TestClient { 2 public static void main(String[] args) { 3 //设置Context的初始状态为ConcreteStateA 4 Context c = new Context(new ConcreteStateA()); 5 //不断的请求,同时更改状态 6 c.request(); 7 c.request(); 8 c.request(); 9 c.request(); 10 11 /** 12 * 打印结果: 13 * 状态A时要做的事。 14 状态B时要做的事 15 状态A时要做的事。 16 状态B时要做的事 17 18 */ 19 } 20 }
UML图:
一个具体的程序员工作的案例:
1 //工作类, 2 public class Work { 3 //工作状态 4 private State current; 5 //构造函数,为工作状态初始化 6 public Work(){ 7 current = new ForenoonState(); 8 } 9 10 //时间,现在多少点了 11 private double hour; 12 //任务是否完成了 13 private boolean finish = false; 14 15 //设置工作状态 16 public void setState(State s){ 17 current = s; 18 } 19 20 //写程序 21 public void writeProgram(){ 22 current.writeProgram(this); 23 } 24 25 //下面是属性的get/set方法 26 public double getHour() { 27 return hour; 28 } 29 30 public void setHour(double hour) { 31 this.hour = hour; 32 } 33 34 public boolean isFinish() { 35 return finish; 36 } 37 38 public void setFinish(boolean finish) { 39 this.finish = finish; 40 } 41 42 43 44 }
1 //抽象状态 2 public abstract class State { 3 /** 4 * 定义一个抽象方法写程序 5 * @param w 6 */ 7 public abstract void writeProgram(Work w); 8 }
1 //上午和中午工作状态的类 2 public class ForenoonState extends State { 3 4 @Override 5 public void writeProgram(Work w) { 6 // TODO Auto-generated method stub 7 if(w.getHour()<12){ 8 System.out.println("当前时间"+w.getHour()+"点,上午工作精神百倍"); 9 }else{ 10 //超过12点,则转入中午工作状态 11 w.setState(new NoonState()); 12 w.writeProgram(); 13 } 14 } 15 16 }
1 //中午工作状态 2 public class NoonState extends State { 3 4 @Override 5 public void writeProgram(Work w) { 6 // TODO Auto-generated method stub 7 if(w.getHour()<13){ 8 System.out.println("当前时间:"+w.getHour()+" 饿了,午饭,犯困,午休"); 9 }else{ 10 //超过13点,则转入下午工作状态 11 w.setState(new AfternoonState()); 12 w.writeProgram(); 13 } 14 } 15 16 }
1 //下午工作状态 2 public class AfternoonState extends State { 3 4 @Override 5 public void writeProgram(Work w) { 6 // TODO Auto-generated method stub 7 if(w.getHour()<17){ 8 System.out.println("当前工作时间:"+w.getHour()+"下午状态还不错,继续努力"); 9 }else{ 10 //超过17点,则转入傍晚工作状态 11 w.setState(new EveningState()); 12 w.writeProgram(); 13 } 14 } 15 16 }
1 //傍晚工作状态 2 public class EveningState extends State { 3 4 @Override 5 public void writeProgram(Work w) { 6 // TODO Auto-generated method stub 7 if(w.isFinish()){ 8 //如果完成任务,则转入下班状态 9 w.setState(new RestState()); 10 w.writeProgram(); 11 }else{ 12 if(w.getHour()<21){ 13 System.out.println("当前时间:"+w.getHour()+"点,加班哦,疲累之极"); 14 }else{ 15 //超过21点,则转入睡眠工作状态 16 w.setState(new SleepingState()); 17 w.writeProgram(); 18 } 19 } 20 } 21 22 }
1 //睡眠状态 2 public class SleepingState extends State { 3 4 @Override 5 public void writeProgram(Work w) { 6 // TODO Auto-generated method stub 7 System.out.println("当前时间:"+w.getHour()+"点,不行了,睡着了"); 8 } 9 10 }
1 //下班休息状态 2 public class RestState extends State { 3 4 @Override 5 public void writeProgram(Work w) { 6 // TODO Auto-generated method stub 7 System.out.println("当前时间:"+w.getHour()+"点下班回家了"); 8 } 9 10 }
测试类:
1 //测试 客户端代码 2 public class TestClient { 3 4 public static void main(String[] args) { 5 //紧急项目 6 Work emergencyProjects = new Work(); 7 emergencyProjects.setHour(9); 8 emergencyProjects.writeProgram(); 9 emergencyProjects.setHour(10); 10 emergencyProjects.writeProgram(); 11 emergencyProjects.setHour(11); 12 emergencyProjects.writeProgram(); 13 emergencyProjects.setHour(12); 14 emergencyProjects.writeProgram(); 15 emergencyProjects.setHour(13); 16 emergencyProjects.writeProgram(); 17 emergencyProjects.setHour(14); 18 emergencyProjects.writeProgram(); 19 emergencyProjects.setHour(17); 20 emergencyProjects.writeProgram(); 21 22 23 //emergencyProjects.setFinish(true); 24 emergencyProjects.setFinish(false); 25 26 27 emergencyProjects.setHour(19); 28 emergencyProjects.writeProgram(); 29 emergencyProjects.setHour(22); 30 emergencyProjects.writeProgram(); 31 32 /** 33 * finish为true时的打印结果: 34 * 当前时间9.0点,上午工作精神百倍 35 当前时间10.0点,上午工作精神百倍 36 当前时间11.0点,上午工作精神百倍 37 当前时间:12.0 饿了,午饭,犯困,午休 38 当前工作时间:13.0下午状态还不错,继续努力 39 当前工作时间:14.0下午状态还不错,继续努力 40 当前时间:17.0点,加班哦,疲累之极 41 当前时间:19.0点下班回家了 42 当前时间:22.0点下班回家了 43 44 45 finish为false的时候的打印结果: 46 当前时间9.0点,上午工作精神百倍 47 当前时间10.0点,上午工作精神百倍 48 当前时间11.0点,上午工作精神百倍 49 当前时间:12.0 饿了,午饭,犯困,午休 50 当前工作时间:13.0下午状态还不错,继续努力 51 当前工作时间:14.0下午状态还不错,继续努力 52 当前时间:17.0点,加班哦,疲累之极 53 当前时间:19.0点,加班哦,疲累之极 54 当前时间:22.0点,不行了,睡着了 55 */ 56 } 57 }
UML图: