C#學(xué)習(xí)筆記之狀態(tài)模式詳解
本文通過例題為大家講解C#學(xué)習(xí)筆記之狀態(tài)模式,供大家參考,具體內(nèi)容如下
題目1:通過代碼描述每一天的不同時(shí)間段的工作效率
分析:
首先確定,工作狀態(tài)指正在工作,或者以及下班這些情況,而這些情況所受影響的因素包括:當(dāng)前時(shí)間以及任務(wù)是否已經(jīng)完成。所以在Work中需要兩個(gè)屬性:hour和finish。然后根據(jù)這兩個(gè)屬性直接判斷當(dāng)前的工作狀態(tài)即可。
實(shí)現(xiàn):
class Program { static void Main(string[] args) { //緊急項(xiàng)目 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> /// 根據(jù)時(shí)間來判斷當(dāng)前的工作狀態(tài)如何 /// /// 方法過長(zhǎng) /// </summary> public void WriteProgram() { if (hour < 12) { Console.WriteLine("當(dāng)前時(shí)間:{0}點(diǎn) 上午工作,精神百倍", hour); } else if (hour < 13) { Console.WriteLine("當(dāng)前時(shí)間:{0}點(diǎn) 餓了,午飯;犯困,午休", hour); } else if (hour < 17) { Console.WriteLine("當(dāng)前時(shí)間:{0}點(diǎn) 下午狀態(tài)還不錯(cuò),繼續(xù)努力", hour); } else { if (finish) { Console.WriteLine("當(dāng)前時(shí)間:{0}點(diǎn) 下班回家了", hour); } else { if (hour < 21) { Console.WriteLine("當(dāng)前時(shí)間:{0}點(diǎn) 加班哦,疲憊至極", hour); } else { Console.WriteLine("當(dāng)前時(shí)間:{0}點(diǎn) 不行了,睡著了。", hour); } } } } } }
題目2:從1中可以很明顯的看出WriteProgram()函數(shù)幾乎承載了所有的判斷處理,且函數(shù)函數(shù)過長(zhǎng),所以在Work類中違背了“單一職責(zé)原則"。
分析:
面向?qū)ο笤O(shè)計(jì)就是希望做到代碼的責(zé)任分解,在這個(gè)情況中,我們將所有的判斷全部添加在了WriteProgram()一個(gè)函數(shù)中,不僅是函數(shù)冗長(zhǎng),如果我臨時(shí)添加新的情況,可能對(duì)原來判斷有出入的時(shí)間也會(huì)造成很多麻煩,對(duì)于將來的修改百害而無一利。
所以我們需要根據(jù)情況來分解函數(shù)和類。
本題目中,我們需要獲得當(dāng)前的工作狀態(tài),而這個(gè)的直接影響因素包括時(shí)間Hour和是否已經(jīng)完成任務(wù)TaskFinished。
所以我們根據(jù)當(dāng)前的時(shí)間可以很明顯的分為不同時(shí)間段,也就是WriteProgram()的if,else都可以自己?jiǎn)为?dú)擁有一個(gè)類,他們都繼承于同一個(gè)抽象類State即可。
然后我們初始化直接進(jìn)入ForenoonState類,畢竟每天早上的時(shí)間不會(huì)變,如果當(dāng)前時(shí)間不再是早上,那么我們就需要進(jìn)入下一個(gè)時(shí)間段進(jìn)行判斷,所以在ForenoonState類中我們需要加入判斷,如果當(dāng)前時(shí)間滿足早上的時(shí)間段,顯示工作狀態(tài),如果當(dāng)前時(shí)間不再是早上的時(shí)間段,那么我們進(jìn)入下一個(gè)時(shí)間段,以此類推,找到我們當(dāng)前時(shí)間段的工作狀態(tài)。
實(shí)現(xiàn):
class Program { static void Main(string[] args) { //緊急項(xiàng)目 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; //初始化進(jìn)入的時(shí)候是上午工作狀態(tài) 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> /// 抽象狀態(tài) /// </summary> public abstract class State { public abstract void WriteProgram(Work w); } /// <summary> /// 上午工作狀態(tài) /// /// 邏輯是:根據(jù)時(shí)間推移,上午工作后,移至中午午飯時(shí)間 /// </summary> public class ForenoonState : State { public override void WriteProgram(Work w) { if (w.Hour < 12) { Console.WriteLine("當(dāng)前時(shí)間:{0} 上午工作,精神百倍", w.Hour); } else { w.SetState(new NoonState()); w.WriteProgram(); } } } /// <summary> /// 中午工作狀態(tài) /// /// 邏輯是:根據(jù)時(shí)間推移,午休時(shí)間后,移至下午工作時(shí)間 /// </summary> public class NoonState : State { public override void WriteProgram(Work w) { if (w.Hour < 13) { Console.WriteLine("當(dāng)前時(shí)間:{0} 餓了,午飯;犯困,午休", w.Hour); } else { w.SetState(new AfternoonState()); w.WriteProgram(); } } } /// <summary> /// 下午工作狀態(tài) /// /// 邏輯是:根據(jù)時(shí)間推移,下午工作后,移至晚間工作狀態(tài) /// </summary> public class AfternoonState : State { public override void WriteProgram(Work w) { if (w.Hour < 17) { Console.WriteLine("當(dāng)前時(shí)間:{0} 下午狀態(tài)還不錯(cuò),繼續(xù)努力", w.Hour); } else { w.SetState(new EveningState()); w.WriteProgram(); } } } /// <summary> /// 晚間工作狀態(tài) /// /// 邏輯是:已完成工作的可以準(zhǔn)點(diǎn)下班,移至下班休息狀態(tài) /// 未完成工作的繼續(xù)加班:這里又分為未超過人體承受能力的(21小時(shí))就繼續(xù)加班(此處已是最底層,沒有再多加其他的操作了) /// 超過21小時(shí)的將移至睡眠狀態(tài) /// </summary> public class EveningState : State { public override void WriteProgram(Work w) { if (w.TaskFinished) { w.SetState(new RestState()); w.WriteProgram(); } else { //最底層,不要再次調(diào)用,會(huì)無限往復(fù)的 if (w.Hour < 21) { Console.WriteLine("當(dāng)前時(shí)間:{0} 加班哦,疲憊至極", w.Hour); } else { w.SetState(new SleepingState()); w.WriteProgram(); } } } } /// <summary> /// 睡眠狀態(tài) /// /// 最底層,不要再次調(diào)用,會(huì)無限往復(fù)的 /// </summary> public class SleepingState : State { public override void WriteProgram(Work w) { Console.WriteLine("當(dāng)前時(shí)間:{0}點(diǎn) 不行了,睡著了", w.Hour); } } /// <summary> /// 下班休息狀態(tài) /// /// 最底層,不要再次調(diào)用,會(huì)無限往復(fù)的 /// </summary> public class RestState : State { public override void WriteProgram(Work w) { if (w.TaskFinished) { Console.WriteLine("當(dāng)前時(shí)間:{0}點(diǎn) 下班回家", w.Hour); } } } }
總結(jié):
這里用到的就是狀態(tài)模式(State):當(dāng)一個(gè)對(duì)象的內(nèi)在狀態(tài)改變時(shí),允許改變其行為,這個(gè)對(duì)象看起來像是改變了其類。
狀態(tài)模式主要解決的是當(dāng)控制一個(gè)對(duì)象狀態(tài)轉(zhuǎn)換的調(diào)節(jié)表達(dá)式過于復(fù)雜時(shí)的情況。把狀態(tài)的判斷邏輯轉(zhuǎn)移到表示不同狀態(tài)的一系列類當(dāng)中,可以吧復(fù)雜的判斷邏輯簡(jiǎn)化。
狀態(tài)模式的好處是將與特定狀態(tài)相關(guān)的行為局部化,并且將不同狀態(tài)的行為分割開來。
注:文中所有代碼及知識(shí)點(diǎn)均來自于《大話設(shè)計(jì)模式》,本人屬于邊學(xué)邊看邊敲代碼邊總結(jié)的階段。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持我們。
欄 目:C#教程
下一篇:C#調(diào)用webservice接口的最新方法教程
本文標(biāo)題:C#學(xué)習(xí)筆記之狀態(tài)模式詳解
本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/5422.html
您可能感興趣的文章
- 01-10C#一個(gè)簡(jiǎn)單的定時(shí)小程序?qū)崿F(xiàn)代碼
- 01-10微信開放平臺(tái)之網(wǎng)站授權(quán)微信登錄功能
- 01-10C#編程自學(xué)之?dāng)?shù)據(jù)類型和變量二
- 01-10C#編程自學(xué)之開篇介紹
- 01-10C#編程自學(xué)之?dāng)?shù)據(jù)類型和變量三
- 01-10C#編程自學(xué)之運(yùn)算符和表達(dá)式
- 01-10C#編程自學(xué)之類和對(duì)象
- 01-10C#編程自學(xué)之?dāng)?shù)據(jù)類型和變量一
- 01-10C#編程自學(xué)之流程控制語句
- 01-10C#影院售票系統(tǒng)畢業(yè)設(shè)計(jì)(1)


閱讀排行
- 1C語言 while語句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10C#通過反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁(yè)無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻播放器左下角滾動(dòng)新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10delphi制作wav文件的方法
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 04-02jquery與jsp,用jquery
- 01-10C#中split用法實(shí)例總結(jié)
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10使用C語言求解撲克牌的順子及n個(gè)骰子