彩虹环绕这秋香、春香、夏香,秋香、春香、夏香环绕着我,这时键盘飞入个人怀中(小朋友,你是否有许多的问号),飞速的敲击键盘,不一下子婀娜多姿的冬香也出如今个人面前。html
有了四大美人相伴,那个人生活要好好从新安排一下,早上谁来服侍我,中午谁来服侍我,下午谁来服侍我,晚上谁来服侍我,想一想都美啊~git
安排...app
Time 、Weather 时间段和天气枚举this
/// <summary> /// 时间段 /// </summary> public enum Time { Morning, Noon, Afternoon, Night } /// <summary> /// 天气 /// </summary> public enum Weather { /// <summary> /// 好天气 /// </summary> Good, /// <summary> /// 坏天气 /// </summary> Bad }
Life类,模拟一天的生活,根据不一样时间段来判断谁来服侍我干什么code
/// <summary> /// 生活 /// </summary> public class Life { /// <summary> /// 时间段 /// </summary> public Time Time { get; set; } /// <summary> /// 天气 /// </summary> public Weather Weather { get; set; } /// <summary> /// 干啥子 /// </summary> public void Doing() { if (Time == Time.Morning) { Console.WriteLine($"\n如今是 早上,春香 服侍我起床~"); } else if (Time == Time.Noon) { Console.WriteLine($"\n如今是 中午,夏香 陪我玩耍~"); if (Weather == Weather.Good) { Console.WriteLine($"天气真好,陪我出去放风筝"); } else { Console.WriteLine($"天气很差,待家给我跳舞"); } } else if (Time == Time.Afternoon) { Console.WriteLine($"\n如今是 下午,秋香 服侍我用餐~"); } else if (Time == Time.Night) { Console.WriteLine($"\n如今是 晚上,冬香 服侍我就寝~"); } else { Console.WriteLine($"\n睡觉中..."); } } }
客户端 开始我一天的生活htm
internal class Program { private static void Main(string[] args) { var life = new Life(); //设置天气 life.Weather = Weather.Good; life.Time = Time.Morning; life.Doing(); life.Time = Time.Noon; life.Doing(); life.Time = Time.Afternoon; life.Doing(); life.Time = Time.Night; life.Doing(); Console.WriteLine("\nHappy Ending~"); Console.ReadLine(); } }
结果展现:对象
如今是 早上,春香 服侍我起床~ 如今是 中午,夏香 陪我玩耍~ 天气真好,陪我出去放风筝 如今是 下午,秋香 服侍我用餐~ 如今是 晚上,冬香 服侍我就寝~
结果仍是挺美好的,可是 这个实现过程非常糟糕。blog
尤为是Life.Doing()接口
/// <summary> /// 干啥子 /// </summary> public void Doing() { if (Time == Time.Morning) { Console.WriteLine($"\n如今是 早上,春香 服侍我起床~"); } else if (Time == Time.Noon) { Console.WriteLine($"\n如今是 中午,夏香 陪我玩耍~"); if (Weather == Weather.Good) { Console.WriteLine($"天气真好,陪我出去放风筝"); } else { Console.WriteLine($"天气很差,待家给我跳舞"); } } else if (Time == Time.Afternoon) { Console.WriteLine($"\n如今是 下午,秋香 服侍我用餐~"); } else if (Time == Time.Night) { Console.WriteLine($"\n如今是 晚上,冬香 服侍我就寝~"); } else { Console.WriteLine($"\n睡觉中..."); } }
这个方法存在如下问题:开发
如何解决上面的问题呢?这时房中升起了四个金光闪闪的大字——状态模式
敲黑板·划重点
定义: 当一个对象的内在状态改变时容许改变其行为,这个对象看起来像是改变了其类。(上面案例中,时间段Time就是Life对象的状态,当Time改变时,Life的行为Doing()就改变了)
做用: 主要解决当控制一个对象状态转换条件表达式过于复杂时的状况。把状态的判断逻辑转移到表示不一样状态的一系列类当中,能够把复杂的判断逻辑简化。
好处: 将与特定状态相关的行为局部化,而且将不一样状态的行为分割开来。
思想: 将特定状态相关的行为都放入一个对象中,因为全部与状态相关的代码都存在于具体的状态对象中,因此经过定义新的子类就能够很容易地增长新的状态和转换。消除庞大的条件分支语句,经过把各类状态转移逻辑分布到状态的子类之间,来减小相互间的依赖。
解决方法已经找到,就开始干吧...
ITimeHandle接口,定义各类时间段(状态)的行为。
public interface ITimeHandle { /// <summary> /// 干啥子 /// </summary> /// <param name="life"></param> public void Doing(Life life); }
Life类,属性中包含ITimeHandle,行为Doing()交个具体的时间段操做(状态对象)。
/// <summary> /// 生活 /// </summary> public class Life { private ITimeHandle _timeHandle; /// <summary> /// 时间段 /// </summary> public Time Time { get; set; } /// <summary> /// 天气 /// </summary> public Weather Weather { get; set; } /// <summary> /// 初始化 一天生活的 时间段 /// </summary> public Life() { //默认设置时间为 上午 _timeHandle = new MorningTime(); } /// <summary> /// 设置时间段对应的操做类 /// </summary> /// <param name="timeHandle"></param> public void SetTimeHandle(ITimeHandle timeHandle) { _timeHandle = timeHandle; } /// <summary> /// 干啥子 /// </summary> public void Doing() { _timeHandle.Doing(this); } }
MorningTime、NoonTime、AfternoonTime、NightTime类实现ITimeHandle接口(这也就是 思想 中:将与特定状态相关的行为局部化。全部与状态相关的代码都存在于具体的状态对象中)。在具体的时间段类中来判断改该作什么(这也就是 做用 中:把状态的判断逻辑转移到表示不一样状态的一系列类当中,能够把复杂的判断逻辑简化)。
/// <summary> /// 早上 干什么 /// </summary> public class MorningTime : ITimeHandle { public void Doing(Life life) { if (life.Time == Time.Morning) { Console.WriteLine($"如今是 早上,春香 服侍我起床~"); } else { life.SetTimeHandle(new NoonTime()); life.Doing(); } } } /// <summary> /// 中午 干什么 /// </summary> public class NoonTime : ITimeHandle { public void Doing(Life life) { if (life.Time == Time.Noon) { Console.WriteLine($"如今是 中午,夏香 陪我玩耍~"); if (life.Weather == Weather.Good) { Console.WriteLine($"天气真好,陪我出去放风筝"); } else { Console.WriteLine($"天气很差,待家给我跳舞"); } } else { life.SetTimeHandle(new AfternoonTime()); life.Doing(); } } } /// <summary> /// 下午 干什么 /// </summary> public class AfternoonTime : ITimeHandle { public void Doing(Life life) { if (life.Time == Time.Afternoon) { Console.WriteLine($"如今是 下午,秋香 服侍我用餐~"); } else { life.SetTimeHandle(new NightTime()); life.Doing(); } } } /// <summary> /// 晚上 干什么 /// </summary> public class NightTime : ITimeHandle { public void Doing(Life life) { if (life.Time == Time.Night) { Console.WriteLine($"如今是 晚上,冬香 服侍我就寝~"); } else { Console.WriteLine($"睡觉中..."); } } }
客户端代码 和 输出结果 同上
如今,咱们再来看看Life.Doing()
/// <summary> /// 干啥子 /// </summary> public void Doing() { _timeHandle.Doing(this); }
方法简洁明了,消除了过多的判断分支。
同时Life类的职责简化了,作到代码的责任分解。符合了我人生信条的第1条和第3条。
这时候,咱们再要增长一个深夜吃夜宵的时间段,Life类就不须要动了。咱们只需增长WeeHoursTime类实现ITimeHandle,调整NightTime中的判断就能够了。
糟糕的问题完美解决,我心甚欢,吟诗一首:
桃花坞里桃花庵,
桃花庵下桃花仙。
桃花仙人敲代码,
桃花运来年复年。
示例代码地址: https://gitee.com/sayook/DesignMode/tree/master/State