设计模式学习笔记——状态模式

来源:互联网 发布:高性能笔记本 编程 编辑:程序博客网 时间:2024/06/13 06:20

状态模式

状态模式,当一个对象的内在状态改变时允许改变其行为,这个对象像是改变了其类。

结构图


代码实现

抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为。
/** * 抽象状态类 * @author xukai * 2016年3月21日 下午10:44:50 */public abstract class State {public abstract void handle(Context context);}
具体状态,每一个子类实现一个与context的一个状态相关的行为。
/** * 具体状态 * @author xukai * 2016年3月21日 下午10:47:00 */public class ConcreteStateA extends State {@Overridepublic void handle(Context context) {context.setState(new ConcreteStateB());}}

/** * 具体状态 * @author xukai * 2016年3月21日 下午10:47:08 */public class ConcreteStateB extends State {@Overridepublic void handle(Context context) {context.setState(new ConcreteStateA());}}
Context类,维护一个ConcreteState子类的实例,即当前的状态。
/** *  * @author xukai 2016年3月21日 下午10:45:56 */public class Context {private State state;public Context(State state) {this.state = state;}public State getState() {return state;}public void setState(State state) {this.state = state;System.out.println("当前状态:" + state.getClass().getSimpleName());}public void request() {state.handle(this);}}
客户端:
public class Client {public static void main(String[] args) {Context context = new Context(new ConcreteStateA());context.request();context.request();context.request();context.request();context.request();}}
控制台:
当前状态:ConcreteStateB当前状态:ConcreteStateA当前状态:ConcreteStateB当前状态:ConcreteStateA当前状态:ConcreteStateB
可以看到两种状态的切换。

demo

问题:解决一天的工作状态切换。
结构图:


代码实现

抽象状态类:
/** * 抽象工作状态 * @author xukai * 2016年3月21日 下午11:01:12 */public abstract class WorkState {public abstract void writeProgram(Work work);}
具体状态类:上午状态类
/** * 上午状态类 * @author xukai * 2016年3月21日 下午11:04:24 */public class ForenoonState extends WorkState {@Overridepublic void writeProgram(Work work) {if(work.getTime() < 12){System.out.println("当前时间:" + work.getTime() + "点,上午工作,精神百倍");}else{work.setState(new NoonState());work.writeProgram();}}}
中午状态类:
/** * 中午状态类 * @author xukai * 2016年3月21日 下午11:29:16 */public class NoonState extends WorkState {@Overridepublic void writeProgram(Work work) {if(work.getTime() < 13){System.out.println("当前时间:" + work.getTime() + "点,饿了,午饭;犯困,午休");}else{work.setState(new AftenoonState());work.writeProgram();}}}
下午状态类:
/** * 下午状态类 * @author xukai * 2016年3月21日 下午11:29:26 */public class AftenoonState extends WorkState {@Overridepublic void writeProgram(Work work) {if(work.getTime() < 17){System.out.println("当前时间:" + work.getTime() + "点,下午状态还不错,继续努力");} else {work.setState(new EveningState());work.writeProgram();}}}
晚上状态类:
/** * 晚上状态类 * @author xukai * 2016年3月21日 下午11:09:51 */public class EveningState extends WorkState {@Overridepublic void writeProgram(Work work) {if(work.isFinish()){work.setState(new RestState());work.writeProgram();}else{if(work.getTime() < 21){System.out.println("当前时间:" + work.getTime() + "点,加班,很累");}else{work.setState(new SleepingState());work.writeProgram();}}}}
修改状态类:
/** * 休息状态类 * @author xukai * 2016年3月21日 下午11:30:09 */public class SleepingState extends WorkState {@Overridepublic void writeProgram(Work work) {System.out.println("当前时间:" + work.getTime() + "点,睡着了");}}
工作类:
/** * 工作类 * @author xukai * 2016年3月21日 下午11:33:30 */public class Work {// 工作状态public WorkState state;// 当前时间private double time;// 是否完成工作private boolean finish = false;public Work() { state = new ForenoonState();}public double getTime() {return time;}public void setTime(double time) {this.time = time;}public void setState(WorkState state) {this.state = state;}public boolean isFinish() {return finish;}public void setFinish(boolean finish) {this.finish = finish;}public void writeProgram() {state.writeProgram(this);}}
客户端测试:
public class Client {public static void main(String[] args) {Work project = new Work();project.setTime(9);project.writeProgram();project.setTime(10);project.writeProgram();project.setTime(12);project.writeProgram();project.setTime(13);project.writeProgram();project.setTime(14);project.writeProgram();project.setTime(17);project.writeProgram();project.setFinish(false);project.setTime(19);project.writeProgram();project.setTime(22);project.writeProgram();}}
输出结果:
当前时间:9.0点,上午工作,精神百倍当前时间:10.0点,上午工作,精神百倍当前时间:12.0点,饿了,午饭;犯困,午休当前时间:13.0点,下午状态还不错,继续努力当前时间:14.0点,下午状态还不错,继续努力当前时间:17.0点,加班,很累当前时间:19.0点,加班,很累当前时间:22.0点,睡着了
通过测试可以看出状态模式消除了庞大的条件分支。
当需要使所有员工都下班的时候,可以在AfternoonState中修改为下班状态类。
/** * 下班状态类 * @author xukai * 2016年3月21日 下午11:30:54 */public class RestState extends WorkState {@Overridepublic void writeProgram(Work work) {System.out.println("当前时间:" + work.getTime() + "下班回家了");}}

使用环境

当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为,那么就可以使用状态模式了。

总结

状态模式通过把各种状态转移逻辑分布到State的子类之间,




1 0
原创粉丝点击