状态模式与状态图
来源:互联网 发布:申通快递单打印软件 编辑:程序博客网 时间:2024/04/26 22:25
说到状态模式,书上给出的解释是:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。看不懂?没关系,毕竟我们都不是小菜。
我们还是从熟悉的状态图说起吧。
故事是这样的:我们来看一个人他的下午时光是如何度过的。在12:00~13:00之间,他在吃饭。过了13点,他就开始午睡。睡醒以后,到了15点,他就出去玩了。也就是说,他的下午时间就在吃饭——睡觉——玩耍之间转换。
用状态图描述,基本上是这个样子的。(简化理解)
联系我们的状态模式,其实状态模式根本上就是几个状态之间的转换,但精髓之处在于如何使得我们的代码更好,设计更完善。这就要结合我们之前讲的设计模式的一些原则和面向对象设计的知识了。首先,方法过长是坏味道。一般来看,状态之间的转换我们会用到很多的分支语句,这样使得一个方法代码过长,那么它的责任就过大了。所以,我们要让代码的责任分解。分解之后,需求改变之后代码的改动就会减少很多了。这也就符合之前说的开放-封闭原则。
用代码来表示:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConsoleApplication2{ class Program { static void Main(string[] args) { //紧急项目 lifeState emergencyProjects = new lifeState(); emergencyProjects.Hour = 12; emergencyProjects.WriteProgram(); emergencyProjects.Hour = 14; emergencyProjects.WriteProgram(); emergencyProjects.Hour = 18; emergencyProjects.WriteProgram(); emergencyProjects.TaskFinished = false; Console.Read(); } } //抽象状态 public abstract class State { public abstract void WriteProgram(lifeState w); } //吃饭状态 public class EatingState : State { public override void WriteProgram(lifeState w) { if (w.Hour <13) { Console.WriteLine( "我在吃饭",w.Hour); } else { w.SetState(new SleepingState()); w.WriteProgram(); //12点之后,就开始午睡了,进入睡觉状态 } } } //睡觉状态 public class SleepingState : State { public override void WriteProgram(lifeState w) { if (w.Hour <15) { Console.WriteLine("我在睡觉",w.Hour); } else { w.SetState(new PlayingState()); w.WriteProgram(); //14点之后,进入玩耍状态 } } } //玩耍状态 public class PlayingState : State { public override void WriteProgram(lifeState w) { Console.WriteLine("我在玩",w.Hour); } } public class lifeState { private State current; public lifeState() { current = new EatingState(); } private double hour; public double Hour //“钟点”属性,状态转换的依据 { get { return hour ; } set {hour = value; } } private bool finish = false; //“任务完成”属性 public bool TaskFinished { get { return finish; } set { finish = value; } } public void SetState(State s) { current = s; } public void WriteProgram() { current.WriteProgram(this); } } }
运行结果:
看完这个小例子,我们来看一下状态模式的结构。我们把特定的状态相关的行为(如吃饭)放在一个对象中,因为代码都在Eating中,所以通过定义新的子类就可以很容易的增加新的状态和转换。把各个状态转移逻辑分布到Sleeping,Playing,Eating之中,减少了相互之间的依赖。
2 1
- 状态模式与状态图
- 状态图 状态表
- 【GOF23设计模式】_状态模式_UML状态图_酒店系统房间状态_线程对象状态切换JAVA250
- EA&UML日拱一卒-状态图::状态
- 状态模式与上机
- 状态图与活动图
- 策略模式与状态模式
- 策略模式与状态模式
- 状态模式与策略模式
- 状态模式与android状态机
- px4的模式与状态
- 一.状态模式与实例
- UML,活动图与状态图
- 状态图
- 状态图
- 状态图
- 状态图
- 状态图
- 【Android】任务和返回栈(tasks and back stack)
- php蜘蛛正常抓取,用户跳转指定页面
- 复杂的分页查询
- Codeforces Round #236 (Div. 2) E. Strictly Positive Matrix 强连通
- Build相关属性和调用系统信息的方法
- 状态模式与状态图
- uitableview学习
- js 添加事件 attachEvent 和 addEventListener 的用法
- 修改boot.img
- 探究如何整合 GLib Main Event Loop 和 Node.js 的 libuv
- Windows Phone 8.1 系列文章索引
- android高分段进阶攻略(8)音乐播放器代码实现一SlidingDrawer实现
- javax.swing.filechooser 文件选择器
- 使用代理对安卓sdk的更新