设计模式学习笔记——状态模式
2016-03-21 23:44
423 查看
状态模式
状态模式,当一个对象的内在状态改变时允许改变其行为,这个对象像是改变了其类。结构图
代码实现
抽象状态类,定义一个接口以封装与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 { @Override public void handle(Context context) { context.setState(new ConcreteStateB()); } }
/** * 具体状态 * @author xukai * 2016年3月21日 下午10:47:08 */ public class ConcreteStateB extends State { @Override public 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 { @Override public 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 { @Override public 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 { @Override public 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 { @Override public 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 { @Override public 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 { @Override public void writeProgram(Work work) { System.out.println("当前时间:" + work.getTime() + "下班回家了"); } }
使用环境
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为,那么就可以使用状态模式了。总结
状态模式通过把各种状态转移逻辑分布到State的子类之间,相关文章推荐
- 工具类:拉伸一张图片(UIImage分类)
- 项目之RFID天线设计
- requests的content与text导致lxml的解析问题
- Spring源码之ApplicationContext(七)获取消息资源
- JAVA 基础 final关键字
- AndroidAutoLayout 屏幕适配
- Codeforces 400B Inna and New Matrix of Candies 【模拟】
- 图示aidl原理
- Android中SQLite数据库小计
- Android——关于Activity跳转的返回(无返回值和有返回值)——无返回值
- Spring源码之ApplicationContext(六)注册BeanPostProcessor
- 使用scm-manager搭建git/svn 代码管理仓库
- Objective-C探究alloc方法的实现
- Mysql绿色版安装配置
- C语言教程:第一节
- cocos2dx三种定时器的使用
- mybatis 数组报错 There is no getter for property named '__frch_item_0'
- Problem F: 删出多余的空格
- 2016年当程序员有前途吗?
- 阿里巴巴电话面试