買了九妹已經快有一年了,從經曆了android2.3.5到深度最佳化的flyme1.1.3,風風雨雨,伴隨著我一起走過。而我對魅族手機的設計也頗為留意。魅族是一個學習型的團隊,很為使用者考慮。今天要講的魅族鬧鐘的新功能——事件定時器。以前看到了,只感覺很實用,近段時間在複習設計模式的時候,突然發現,魅族的這個新功能,盡然就是狀態模式的真實執行個體。
為了讓瞭解的和不瞭解的狀態模式的同行們都看得懂我接下來說的,我先簡要的介紹一下這個狀態模式:
狀態模式 State
狀態模式允許一個對象在其內部狀態改變時改變它的行為,讓對象看起來似乎修改了它的類。
狀態模式就是把系統的多個狀態分割開來,分布到State的子類中,消除了龐大的分支語句,減少了耦合,同時也很容易增加新的狀態的和轉換。
這就相當於一個Schedule或School Timetable一樣,時間的改變,我們的行程或課程也隨之改變。
今天藉助M9的新功能,跟大家來實驗一下用狀態模式做一次清蒸鯉魚,讓你在學習設計模式的時候,還另有收穫。別的不多說,先:
其中狀態有5種:PrepareTime,BoillingState,SteamshState,TurnOffFishState,SaucingState,對應操作的五個步驟。
/// <summary> /// 製作清蒸魚 /// </summary> public class SteamFish { private State current;//儲存目前狀態 public SteamFish() { current = new PrepareState(); } //總計時 private int timecount; //記錄當前操作用時 private int time = 0; public int TimeCount { get { return timecount; } set { //記錄當前操作用時 time = timecount; timecount = value; } } //任務完成標識 private bool finish = false; public bool TaskFinished { get { return finish; } set { finish = value; } } //切換狀態 public void SetState(State s) { current = s; } //清蒸操作 public void SteamFishes() { //繼續操作 current.Steam(this,time); } }
/// <summary> /// 抽象狀態 /// </summary> public abstract class State { //清蒸魚 public abstract void Steam(SteamFish sf,int time); }
/// <summary> /// 準備狀態 /// </summary> public class PrepareState : State { private static int statictime;//本狀態累積所用時間(秒) public override void Steam(SteamFish sf, int time) { statictime += (sf.TimeCount - time);//計算本狀態累積所用時間(秒) if (sf.TimeCount <= 60) { if (statictime == (sf.TimeCount - time)) { Console.WriteLine("\r【清蒸魚菜譜教程】\n\n①.將少許薑、鹽、麻油放入魚腹。" + "\t\t" + "所需時間 1分0秒 ,已用去 {0}分{1}秒。\n", statictime / 60, statictime % 60); } else { Console.WriteLine("\t\t\t\t\t親,請稍等 ,已維持該狀態 {0}分{1}秒。\n", statictime / 60, statictime % 60); } } else { statictime = 0; //下一步操作是:燒水 sf.SetState(new BoillingState()); sf.SteamFishes(); } } }
/// <summary> /// 燒水狀態 /// </summary> public class BoillingState:State { private static int statictime;//本狀態累積所用時間(秒) public override void Steam(SteamFish sf, int time) { statictime += (sf.TimeCount - time);//計算本狀態累積所用時間(秒) if (sf.TimeCount <= 150) { if (statictime == (sf.TimeCount - time)) { Console.WriteLine("②.往鍋裡放入適量的水並燒開。\t\t所需時間 1分30秒,已用去 {0}分{1}秒。\n", statictime / 60, statictime % 60); } else { Console.WriteLine("\t\t\t\t\t親,請稍等 ,已維持該狀態 {0}分{1}秒。\n", statictime / 60, statictime % 60); } } else { statictime = 0; //下一步操作是:煮魚 sf.SetState(new SteamFishState()); sf.SteamFishes(); } } }
/// <summary> /// 蒸魚狀態 /// </summary> class SteamFishState:State { private static int statictime;//本狀態累積所用時間(秒) public override void Steam(SteamFish sf, int time) { statictime += (sf.TimeCount - time);//計算本狀態累積所用時間(秒) if (sf.TimeCount <= 570) { if (statictime == (sf.TimeCount - time)) { Console.WriteLine("③.把魚放入鍋中,合上蓋子。" + "\t\t" + "所需時間 7分0秒,已用去 {0}分{1}秒。\n", statictime / 60, statictime % 60); } else { Console.WriteLine("\t\t\t\t\t親,請稍等 ,已維持該狀態 {0}分{1}秒。\n", statictime / 60, statictime % 60); } } else { statictime = 0; //下一步操作是:關火 sf.SetState(new TurnOffState()); sf.SteamFishes(); } } }
/// <summary> /// 關火狀態 /// </summary> class TurnOffState:State { private static int statictime;//本狀態累積所用時間(秒) public override void Steam(SteamFish sf,int time) { statictime += (sf.TimeCount - time);//計算本狀態累積所用時間(秒) if (sf.TimeCount <= 870) { if (statictime == (sf.TimeCount - time)) { Console.WriteLine("④.關火,別開啟蓋!" + "\t\t\t" + "所需時間 5分0秒,已用去 {0}分{1}秒。\n", statictime / 60, statictime % 60); } else { Console.WriteLine("\t\t\t\t\t親,請稍等 ,已維持該狀態 {0}分{1}秒。\n", statictime / 60, statictime % 60); } } else { statictime = 0; //下一步操作是:燒水 sf.SetState(new SaucingState()); sf.SteamFishes(); } } }
/// <summary> /// 調料狀態 /// </summary> class SaucingState:State { private static int statictime;//本狀態累積所用時間(秒) public override void Steam(SteamFish sf, int time) { statictime += (sf.TimeCount - time);//計算本狀態累積所用時間(秒) if (sf.TimeCount <= 880) { if (statictime == (sf.TimeCount - time)) { Console.WriteLine("⑤.開蓋,調料淋遍魚身!" + "\t\t\t" + "所需時間 0分10秒,已用去 {0}分{1}秒。\n", statictime / 60, statictime % 60); } else { Console.WriteLine("\t\t\t\t\t親,請稍等 ,已維持該狀態 {0}分{1}秒。\n", statictime / 60, statictime % 60); } } else { sf.TaskFinished = true; Console.WriteLine("開搶了,再不搶就沒了!"); } } }
用戶端代碼:
static void Main(string[] args) { //【清蒸魚操作教程】 SteamFish sf = new SteamFish(); sf.TimeCount = 60; sf.SteamFishes(); sf.TimeCount = 100; sf.SteamFishes(); sf.TimeCount = 150; sf.SteamFishes(); sf.TimeCount = 570; sf.SteamFishes(); sf.TimeCount = 600; sf.SteamFishes(); sf.TimeCount = 870; sf.SteamFishes(); sf.TimeCount = 880; sf.SteamFishes(); sf.TimeCount = 1000; sf.SteamFishes(); Console.Read(); }
效果: