【设计模式】无尽加班何时休 --- 状态模式

一,概述

状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。

  意图:允许一个对象在其内部状态改变时改变它的行为

  适用场景:

  1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。

  2.一个操作中含有庞大的多分支结构,并且这些分支决定于对象的状态。

二,示例

题目:根据不同时间段,显示不同时间段的精神状态

1)面向过程版本

class Program { static int Hour = 0; static bool WorkFinished = false; static void Main(string[] args) { Hour = 9; WriteProgram(); Hour = 10; WriteProgram(); Hour = 12; WriteProgram(); Hour = 13; WriteProgram(); Hour = 14; WriteProgram(); Hour = 17; WorkFinished = true; //WorkFinished = false; WriteProgram(); Hour = 19; WriteProgram(); Hour = 22; WriteProgram(); Console.Read(); } public static void WriteProgram() { if (Hour < 12) { Console.WriteLine("当前时间:{0}点 上午工作,精神百倍", Hour); } else if (Hour < 13) { Console.WriteLine("当前时间:{0}点 饿了,午饭;犯困,午休。", Hour); } else if (Hour < 17) { Console.WriteLine("当前时间:{0}点 下午状态还不错,继续努力", Hour); } else { if (WorkFinished) { Console.WriteLine("当前时间:{0}点 下班回家了", Hour); } else { if (Hour < 21) { Console.WriteLine("当前时间:{0}点 加班哦,疲累之极", Hour); } else { Console.WriteLine("当前时间:{0}点 不行了,睡着了。", Hour); } } } } }


2)工作状态分类版本

缺点:WriteProgram 中有太多的判断,如果更改时间段可能要改好几个,而且改错的风险极大

class Program { static void Main(string[] args) //通过类设置不同hour 从而打印不同状态 { //紧急项目 Work emergencyProjects = new Work(); emergencyProjects.Hour = 9; emergencyProjects.WriteProgram(); emergencyProjects.Hour = 10; emergencyProjects.WriteProgram(); emergencyProjects.Hour = 12; emergencyProjects.WriteProgram(); emergencyProjects.Hour = 13; emergencyProjects.WriteProgram(); emergencyProjects.Hour = 14; emergencyProjects.WriteProgram(); emergencyProjects.Hour = 17; //emergencyProjects.WorkFinished = true; emergencyProjects.TaskFinished = false; emergencyProjects.WriteProgram(); emergencyProjects.Hour = 19; emergencyProjects.WriteProgram(); emergencyProjects.Hour = 22; emergencyProjects.WriteProgram(); Console.Read(); } } //工作 public class Work { //钟点 private int hour; public int Hour { get { return hour; } set { hour = value; } } //任务完成 private bool finish = false; public bool TaskFinished { get { return finish; } set { finish = value; } } public void WriteProgram() { if (hour < 12) { Console.WriteLine("当前时间:{0}点 上午工作,精神百倍", hour); } else if (hour < 13) { Console.WriteLine("当前时间:{0}点 饿了,午饭;犯困,午休。", hour); } else if (hour < 17) { Console.WriteLine("当前时间:{0}点 下午状态还不错,继续努力", hour); } else { if (finish) { Console.WriteLine("当前时间:{0}点 下班回家了", hour); } else { if (hour < 21) { Console.WriteLine("当前时间:{0}点 加班哦,疲累之极", hour); } else { Console.WriteLine("当前时间:{0}点 不行了,睡着了。", hour); } } } } }


3)状态模式

主要解决的问题:当控制一个对象状态转移的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中。可以把复杂的逻辑简化。

优点:将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。

消除庞大的条件分支语句。

class Program { static void Main(string[] args) { //紧急项目 Work emergencyProjects = new Work(); emergencyProjects.Hour = 9; emergencyProjects.WriteProgram(); emergencyProjects.Hour = 10; emergencyProjects.WriteProgram(); emergencyProjects.Hour = 12; emergencyProjects.WriteProgram(); emergencyProjects.Hour = 13; emergencyProjects.WriteProgram(); emergencyProjects.Hour = 14; emergencyProjects.WriteProgram(); emergencyProjects.Hour = 17; //emergencyProjects.WorkFinished = true; emergencyProjects.TaskFinished = false; emergencyProjects.WriteProgram(); emergencyProjects.Hour = 19; emergencyProjects.WriteProgram(); emergencyProjects.Hour = 22; emergencyProjects.WriteProgram(); Console.Read(); } } //抽象状态 public abstract class State { public abstract void WriteProgram(Work w); } //上午工作状态 public class ForenoonState : State { public override void WriteProgram(Work w) { if (w.Hour < 12) { Console.WriteLine("当前时间:{0}点 上午工作,精神百倍", w.Hour); } else { w.SetState(new NoonState()); w.WriteProgram(); } } } //中午工作状态 public class NoonState : State { public override void WriteProgram(Work w) { if (w.Hour < 13) { Console.WriteLine("当前时间:{0}点 饿了,午饭;犯困,午休。", w.Hour); } else { w.SetState(new AfternoonState()); w.WriteProgram(); } } } //下午工作状态 public class AfternoonState : State { public override void WriteProgram(Work w) { if (w.Hour < 17) { Console.WriteLine("当前时间:{0}点 下午状态还不错,继续努力", w.Hour); } else { w.SetState(new EveningState()); w.WriteProgram(); } } } //晚间工作状态 public class EveningState : State { public override void WriteProgram(Work w) { if (w.TaskFinished) { w.SetState(new RestState()); w.WriteProgram(); } else { if (w.Hour < 21) { Console.WriteLine("当前时间:{0}点 加班哦,疲累之极", w.Hour); } else { w.SetState(new SleepingState()); w.WriteProgram(); } } } } //睡眠状态 public class SleepingState : State { public override void WriteProgram(Work w) { Console.WriteLine("当前时间:{0}点 不行了,睡着了。", w.Hour); } } //下班休息状态 public class RestState : State { public override void WriteProgram(Work w) { Console.WriteLine("当前时间:{0}点 下班回家了", w.Hour); } } //工作 public class Work { private State current; public Work() { current = new ForenoonState(); } 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); } }


三,状态模式模板

class Program { static void Main(string[] args) { Context c = new Context(new ConcreteStateA()); c.Request(); c.Request(); c.Request(); c.Request(); Console.Read(); } } class Context { private State state; public Context(State state) { this.state = state; } public State State { get { return state; } set { state = value; Console.WriteLine("当前状态:" + state.GetType().Name); } } public void Request() { state.Handle(this); } } abstract class State { public abstract void Handle(Context context); } class ConcreteStateA : State { public override void Handle(Context context) { context.State = new ConcreteStateB(); } } class ConcreteStateB : State { public override void Handle(Context context) { context.State = new ConcreteStateA(); } }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值