我們就以工程師的一天:Eat、Coding、Sleep 三種狀態,來示範 STATE 模式 STATE 模式是由以下三個部分組成:
Context:用來控制所有的狀態,其會是與客戶端的接口,客戶端只會與 Context 互動 
State:定義各個狀態的抽象方法,ConcreteState 會繼承 State 並實作其方法 
ConcreteState:Eat、Coding、Sleep,三種狀態的實作 
 
 
 
定義 Context 用列舉定義狀態 因我們有三種 State,所以我用列舉定義出 State,待會 Context 裡的 GetState 方法會用到
1 2 3 4 5 6 7 8 9 10 11 12 namespace  DemoCode.DesignPattern.State {                    public  enum  StateEnum     {         Eat,         Sleep,         Coding     } } 
 
定義 Context 定義客戶端的接口 Context,其為所有狀態的控制中心,客戶端只能透過它執行各狀態的行為
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 using  System;namespace  DemoCode.DesignPattern.State {                    public  class  SoftwareEngineer      {         private  State _itsState;         private  Eat _eatState;         private  Sleep _sleepState;         private  Coding _codeingState;                                    public  SoftwareEngineer ( )          {            this ._eatState = new  Eat();             this ._sleepState = new  Sleep();             this ._codeingState = new  Coding();                          this ._itsState = this ._eatState;         }                                             public  string  GetCurrentStateName ( )          {            Console.WriteLine($"現在狀態:{this ._itsState.StateName()} " );             return  this ._itsState.StateName();         }                                                      public  State GetState (StateEnum state )          {            switch  (state)             {                 case  StateEnum.Eat:                     return  this ._eatState;                 case  StateEnum.Sleep:                     return  this ._sleepState;                 case  StateEnum.Coding:                     return  this ._codeingState;                 default :                     throw  new  ArgumentException();             }         }                                             public  void  SetState (State state )          {            this ._itsState = state;         }                                    public  void  Action ( )          {            this ._itsState.Action(this );         }     } } 
 
定義 State 定義基底類別,各狀態類別會繼承此類別,並實作其方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 namespace  DemoCode.DesignPattern.State {     public  abstract  class  State      {                                             public  abstract  string  StateName ( ) ;                                    public  virtual  void  Action (SoftwareEngineer softwareEngineer )          {        }     } } 
 
實作 ConcreteState 這邊放上 Eat.cs 的程式碼,其他兩種狀態差不多 每個狀態類別實作基底類別宣告的方法,並自行決定完成動作後,下個狀態為何
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 using  System;namespace  DemoCode.DesignPattern.State {                    public  class  Eat  : State      {                                             public  override  string  StateName ( )          {            return  "Eat" ;         }                                             public  override  void  Action (SoftwareEngineer softwareEngineer )          {            Console.WriteLine("該吃飯了" );                          Console.WriteLine("吃完飯該寫程式了" );             var  nextState = softwareEngineer.GetState(StateEnum.Coding);             softwareEngineer.SetState(nextState);         }     } } 
 
結果 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 namespace  DemoCode {     class  Program      {         static  void  Main (string [] args )          {            var  engineer = new  SoftwareEngineer();             Console.WriteLine("Step01:" );             engineer.GetCurrentStateName();             engineer.Action();             Console.WriteLine("Step02:" );             engineer.GetCurrentStateName();             engineer.Action();             Console.WriteLine("Step03:" );             engineer.GetCurrentStateName();             engineer.Action();             Console.WriteLine("Step04:" );             engineer.GetCurrentStateName();             engineer.Action();         }     } } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Step01: 現在狀態:Eat 該吃飯了 吃完飯該寫程式了 Step02: 現在狀態:Coding 該寫程式了 寫完程式該睡覺了 Step03: 現在狀態:Sleep 該睡覺了 睡完覺該吃飯了 Step04: 現在狀態:Eat 該吃飯了 吃完飯該寫程式了 
 
完整程式碼請參考 
結論 STATE 模式的好處是將各 State 的邏輯分離,在管理複雜的系統行為時很有幫助 而 STATE 模式與 STRATEGY 模式看起來很相近,但差別在於,前者知道各 State 的存在,且能透過 Context 進行修改,後者則相反。如下圖可看出,Context 並不知道是哪個 Contrete Strategy 實作 method 的,而 State 會知道
Strategy 模式
參考 STATE 模式.無瑕的程式碼 敏捷完整篇:物件導向原則、設計模式與 C# 實踐 wiki - state pattern 狀態模式-State Pattern 狀態模式 | State Pattern [Design Pattern] State 狀態模式