彩虹環繞這秋香、春香、夏香,秋香、春香、夏香環繞着我,這時鍵盤飛入個人懷中(小朋友,你是否有許多的問號),飛速的敲擊鍵盤,不一下子婀娜多姿的冬香也出如今個人面前。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