狀態模式(State):
在軟體開發程序中,應用程式可能會根據不同的情況作出不同的處理,最直接的解決方案是將這些所有可能發生的情況全都考慮到,然后使用if else陳述句來做狀態判斷來進行不同情況的處理,但對復雜狀態的判斷就顯得"力不從心了",隨著增加新的狀態或者修改一個狀體if else(或switch case)陳述句的增多或者修改)可能會引起很大的修改,違反OCP原則,狀態模式就是在當控制一個物件狀態轉換的條件運算式過于復雜時,把相關"判斷邏輯"提取出來,放到一系列的狀態類當中,這樣可以把原來復雜的邏輯判斷簡單化,
狀態模式的角色:
1)環境類(Context):也稱為背景關系,它定義了客戶感興趣的介面,維護一個當前狀態,并將與狀態相關的操作委托給當前狀態物件來處理,
2)抽象狀態類(AbstractState):定義一個介面以封裝與Context的一個特定狀態相關的行為,
3)具體狀態類(ConcreteState):實作抽象狀態所對應的行為,
狀態模式的代碼實作:
1 internal class Program 2 { 3 private static void Main(string[] args) 4 { 5 // Setup context in a state 6 Context c = new Context(new ConcreteStateA()); 7 8 // Issue requests, which toggles state 9 c.Request();10 c.Request();11 }12 }13 14 public abstract class AbstractState15 {16 public abstract void Handler(Context context);17 }18 19 public class Context20 {21 private AbstractState state;22 23 public Context(AbstractState state)24 {25 this.state = state;26 }27 28 public AbstractState State29 {30 get31 {32 return state;33 }34 set35 {36 state = value;37 Console.WriteLine("State: " + state.GetType().Name);38 }39 }40 41 public void Request()42 {43 state.Handler(this);44 }45 }46 47 public class ConcreteStateA : AbstractState48 {49 public override void Handler(Context context)50 {51 context.State = new ConcreteStateB();52 }53 }54 55 public class ConcreteStateB : AbstractState56 {57 public override void Handler(Context context)58 {59 context.State = new ConcreteStateC();60 }61 }62 63 public class ConcreteStateC : AbstractState64 {65 public override void Handler(Context context)66 {67 context.State = new ConcreteStateA();68 }69 }
實體:(以電燈開關為例)
1 internal class Program 2 { 3 private static void Main(string[] args) 4 { 5 Light light = new Light(new LightOff()); 6 light.PressSwich(); 7 light.PressSwich(); 8 } 9 }10 11 /// <summary>12 /// 抽象電燈狀態類13 /// </summary>14 public abstract class LightState15 {16 public abstract void PressSwich(Light light);17 }18 19 public class Light20 {21 private LightState state;22 23 public Light(LightState state)24 {25 this.state = state;26 }27 28 public LightState State29 {30 get { return state; }31 set { state = value; }32 }33 34 public void PressSwich()35 {36 state.PressSwich(this);37 }38 }39 40 /// <summary>41 /// 電燈打開狀態42 /// </summary>43 public class LightOn : LightState44 {45 public override void PressSwich(Light light)46 {47 Console.WriteLine("Turn off the light.");48 light.State = new LightOff();49 }50 }51 52 /// <summary>53 /// 電燈關閉狀態54 /// </summary>55 public class LightOff : LightState56 {57 public override void PressSwich(Light light)58 {59 Console.WriteLine("Turn on the light.");60 light.State = new LightOn();61 }62 }
狀態模式的優缺點:
優點:
1)狀態模式將與特定狀態相關的行為區域化到一個狀態中,并且將不同狀態的行為分割開來,滿足“單一職責原則”,
2)減少物件間的相互依賴,將不同的狀態引入獨立的物件中會使得狀態轉換變得更加明確,且減少物件間的相互依賴,
3)有利于程式的擴展,通過定義新的子類很容易地增加新的狀態和轉換,
缺點:
1)狀態模式的使用必然會增加系統的類與物件的個數,
2)狀態模式的結構與實作都較為復雜,如果使用不當會導致程式結構和代碼的混亂,
狀態模式的應用場景:
1)當一個物件的行為取決于它的狀態,并且它必須在運行時根據狀態改變它的行為,
2)一個操作中含有龐大的分支結構,并且這些分支決定于物件的狀態,
狀態模式與策略模式的區別:
從UML圖上我們會發現這兩種設計模式幾乎一摸一樣,都是利用多型把一些操作分配到一組相關的簡單的類中,然而在顯示世界中,策略模式和狀態模式是兩種完全不同的思想,對狀態進行建模時,狀態遷移是一個核心問題;但策略模式與遷移毫無關系,策略模式允許一個客戶選擇或提供一種策略,
狀態模式與責任鏈模式的區別:
職責鏈模式和狀態模式都可以解決if分支過多的問題,從定義來看,狀態模式是一個物件內在狀態發生改變(一個物件,相對穩定,處理完一個物件下一個物件一般已確定),而職責鏈模式是多個物件之間的改變(多個物件之間的話,就會出現某個物件不存在的問題,且該模式由客戶端指定,不穩定),這也說明了這兩個模式處理的情況不同,
參考:https://www.runoob.com/w3cnote/state-vs-strategy.html
https://blog.csdn.net/hguisu/article/details/7557252
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/42124.html
標籤:設計模式
上一篇:結構型設計模式(下)
下一篇:行為型設計模式(上)
