買了九妹已經快有一年了,從經歷了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();
}
~~~
效果:
