C# 設計形式系列教程-狀況形式。本站提示廣大學習愛好者:(C# 設計形式系列教程-狀況形式)文章只能為提供參考,不一定能成為您想要的結果。以下是C# 設計形式系列教程-狀況形式正文
1. 概述
當一個對象的內涵狀況轉變時許可轉變其行動,這個對象看起來像是轉變了其類。
2. 處理的成績
重要處理的是當掌握一個對象狀況轉換的前提表達式過於龐雜時的情形。把狀況的斷定邏輯轉移到表現分歧的一系列類傍邊,可以把龐雜的邏輯斷定簡略化。
3. 形式中的腳色
3.1 高低文情況(Context):它界說了客戶法式須要的接口並保護一個詳細狀況腳色的實例,將與狀況相干的操作拜托給以後的Concrete State對象來處置。
3.2 籠統狀況(State):界說一個接口以封裝應用高低文情況的的一個特定狀況相干的行動。
3.3 詳細狀況(Concrete State):完成籠統狀況界說的接口。
4. 形式解讀
4.1 狀況形式的類圖
4.2 狀況形式的代碼完成
/// <summary> /// Context類,保護一個ConcreteState子類的實例,這個實例界說以後的狀況。 /// </summary> public class Context { private State state; /// <summary> /// 界說Context的初始狀況 /// </summary> /// <param name="state"></param> public Context(State state) { this.state = state; } /// <summary> /// 可讀寫的狀況屬性,用於讀取和設置新狀況 /// </summary> public State State { get { return state; } set { state = value; } } /// <summary> /// 對要求做處置,並設置下一個狀況 /// </summary> public void Request() { state.Handle(this); } } /// <summary> /// 籠統狀況類,界說一個接口以封裝與Context的一個特定狀況相干的行動 /// </summary> public abstract class State { public abstract void Handle(Context context); } /// <summary> /// 詳細狀況類,每個子類完成一個與Context的一個狀況相干的行動 /// </summary> public class ConcreteStateA : State { /// <summary> /// 設置ConcreteStateA的下一個狀況是ConcreteStateB /// </summary> /// <param name="context"></param> public override void Handle(Context context) { Console.WriteLine("以後狀況是 A."); context.State = new ConcreteStateB(); } } public class ConcreteStateB : State { /// <summary> /// 設置ConcreteStateB的下一個狀況是ConcreteSateA /// </summary> /// <param name="context"></param> public override void Handle(Context context) { Console.WriteLine("以後狀況是 B."); context.State = new ConcreteStateA(); } }
4.3 客戶端挪用
class Program { static void Main(string[] args) { // 設置Context的初始狀況為ConcreteStateA Context context = new Context(new ConcreteStateA()); // 赓續地停止要求,同時更改狀況 context.Request(); context.Request(); context.Request(); context.Request(); Console.Read(); } }
運轉成果
5. 形式總結
5.1 長處
5.1.1 狀況形式將與特定狀況相干的行動部分化,而且將分歧狀況的行動朋分開來。
5.1.2 一切狀況相干的代碼都存在於某個ConcereteState中,所以經由過程界說新的子類很輕易地增長新的狀況和轉換。
5.1.3 狀況形式經由過程把各類狀況轉移邏輯分不到State的子類之間,來削減互相間的依附。
5.2 缺陷
5.2.1 招致較多的ConcreteState子類
5.3 實用場景
5.3.1 當一個對象的行動取決於它的狀況,而且它必需在運轉時辰依據狀況轉變它的行動時,便可以斟酌應用狀況形式來。
5.3.2 一個操作中含有宏大的分支構造,而且這些分支決議於對象的狀況。
6. 運用舉例:電燈有兩個狀況,開(亮)與關(不亮),上面就用狀況形式來完成對電燈的掌握。
6.1 類圖
6.2 完成代碼
/// <summary> /// 電燈類,對應形式中的Context類 /// </summary> public class Light { private LightState state; public Light(LightState state) { this.state = state; } /// <summary> /// 按下電燈開關 /// </summary> public void PressSwich() { state.PressSwich(this); } public LightState State { get { return state; } set { state = value; } } } /// <summary> /// 籠統的電燈狀況類,相當於State類 /// </summary> public abstract class LightState { public abstract void PressSwich(Light light); } /// <summary> /// 詳細狀況類, 開 /// </summary> public class On : LightState { /// <summary> /// 在開狀況下,按下開關則切換到關的狀況。 /// </summary> /// <param name="light"></param> public override void PressSwich(Light light) { Console.WriteLine("Turn off the light."); light.State = new Off(); } } /// <summary> /// 詳細狀況類,關 /// </summary> public class Off: LightState { /// <summary> /// 在關狀況下,按下開關則翻開電燈。 /// </summary> /// <param name="light"></param> public override void PressSwich(Light light) { Console.WriteLine("Turn on the light."); light.State = new On(); } }
6.3 客戶端代碼
class Program { static void Main(string[] args) { // 初始化電燈,原始狀況為關 Light light = new Light(new Off()); // 第一次按下開關,翻開電燈 light.PressSwich(); // 第二次按下開關,封閉電燈 light.PressSwich(); Console.Read(); } }
履行成果