您好,登錄后才能下訂單哦!
本文通過例題為大家講解C#學習筆記之狀態模式,供大家參考,具體內容如下
題目1:通過代碼描述每一天的不同時間段的工作效率
分析:
首先確定,工作狀態指正在工作,或者以及下班這些情況,而這些情況所受影響的因素包括:當前時間以及任務是否已經完成。所以在Work中需要兩個屬性:hour和finish。然后根據這兩個屬性直接判斷當前的工作狀態即可。
實現:
class Program { static void Main(string[] args) { //緊急項目 Work emergencyProject = new Work(); emergencyProject.Hour = 9; emergencyProject.WriteProgram(); emergencyProject.Hour = 10; emergencyProject.WriteProgram(); emergencyProject.Hour = 12; emergencyProject.WriteProgram(); emergencyProject.Hour = 13; emergencyProject.WriteProgram(); emergencyProject.Hour = 14; emergencyProject.WriteProgram(); emergencyProject.Hour = 17; emergencyProject.Finish = false; emergencyProject.WriteProgram(); emergencyProject.Hour = 19; emergencyProject.WriteProgram(); emergencyProject.Hour = 22; emergencyProject.WriteProgram(); Console.Read(); } public class Work { private int hour; private bool finish = false; public int Hour { get { return hour; } set { hour = value; } } public bool Finish { get { return finish; } set { finish = value; } } /// <summary> /// 根據時間來判斷當前的工作狀態如何 /// /// 方法過長 /// </summary> 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); } } } } } }
題目2:從1中可以很明顯的看出WriteProgram()函數幾乎承載了所有的判斷處理,且函數函數過長,所以在Work類中違背了“單一職責原則"。
分析:
面向對象設計就是希望做到代碼的責任分解,在這個情況中,我們將所有的判斷全部添加在了WriteProgram()一個函數中,不僅是函數冗長,如果我臨時添加新的情況,可能對原來判斷有出入的時間也會造成很多麻煩,對于將來的修改百害而無一利。
所以我們需要根據情況來分解函數和類。
本題目中,我們需要獲得當前的工作狀態,而這個的直接影響因素包括時間Hour和是否已經完成任務TaskFinished。
所以我們根據當前的時間可以很明顯的分為不同時間段,也就是WriteProgram()的if,else都可以自己單獨擁有一個類,他們都繼承于同一個抽象類State即可。
然后我們初始化直接進入ForenoonState類,畢竟每天早上的時間不會變,如果當前時間不再是早上,那么我們就需要進入下一個時間段進行判斷,所以在ForenoonState類中我們需要加入判斷,如果當前時間滿足早上的時間段,顯示工作狀態,如果當前時間不再是早上的時間段,那么我們進入下一個時間段,以此類推,找到我們當前時間段的工作狀態。
實現:
class Program { static void Main(string[] args) { //緊急項目 Work emergencyProject = new Work(); emergencyProject.Hour = 9; emergencyProject.WriteProgram(); emergencyProject.Hour = 10; emergencyProject.WriteProgram(); emergencyProject.Hour = 12; emergencyProject.WriteProgram(); emergencyProject.Hour = 13; emergencyProject.WriteProgram(); emergencyProject.Hour = 14; emergencyProject.WriteProgram(); emergencyProject.Hour = 17; emergencyProject.TaskFinished = false; emergencyProject.WriteProgram(); emergencyProject.Hour = 19; emergencyProject.WriteProgram(); emergencyProject.Hour = 22; emergencyProject.WriteProgram(); Console.Read(); } public class Work { private int hour; private bool finish = false; private State current; //初始化進入的時候是上午工作狀態 public Work() { current = new ForenoonState(); } public int Hour { get { return hour; } set { hour = value; } } public bool TaskFinished { get { return finish; } set { finish = value; } } public void SetState(State s) { current = s; } public void WriteProgram() { current.WriteProgram(this); } } /// <summary> /// 抽象狀態 /// </summary> public abstract class State { public abstract void WriteProgram(Work w); } /// <summary> /// 上午工作狀態 /// /// 邏輯是:根據時間推移,上午工作后,移至中午午飯時間 /// </summary> 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(); } } } /// <summary> /// 中午工作狀態 /// /// 邏輯是:根據時間推移,午休時間后,移至下午工作時間 /// </summary> 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(); } } } /// <summary> /// 下午工作狀態 /// /// 邏輯是:根據時間推移,下午工作后,移至晚間工作狀態 /// </summary> 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(); } } } /// <summary> /// 晚間工作狀態 /// /// 邏輯是:已完成工作的可以準點下班,移至下班休息狀態 /// 未完成工作的繼續加班:這里又分為未超過人體承受能力的(21小時)就繼續加班(此處已是最底層,沒有再多加其他的操作了) /// 超過21小時的將移至睡眠狀態 /// </summary> 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(); } } } } /// <summary> /// 睡眠狀態 /// /// 最底層,不要再次調用,會無限往復的 /// </summary> public class SleepingState : State { public override void WriteProgram(Work w) { Console.WriteLine("當前時間:{0}點 不行了,睡著了", w.Hour); } } /// <summary> /// 下班休息狀態 /// /// 最底層,不要再次調用,會無限往復的 /// </summary> public class RestState : State { public override void WriteProgram(Work w) { if (w.TaskFinished) { Console.WriteLine("當前時間:{0}點 下班回家", w.Hour); } } } }
總結:
這里用到的就是狀態模式(State):當一個對象的內在狀態改變時,允許改變其行為,這個對象看起來像是改變了其類。
狀態模式主要解決的是當控制一個對象狀態轉換的調節表達式過于復雜時的情況。把狀態的判斷邏輯轉移到表示不同狀態的一系列類當中,可以吧復雜的判斷邏輯簡化。
狀態模式的好處是將與特定狀態相關的行為局部化,并且將不同狀態的行為分割開來。
注:文中所有代碼及知識點均來自于《大話設計模式》,本人屬于邊學邊看邊敲代碼邊總結的階段。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。