状态模式:状态模式允许一个对象在其内部状态改变的时候改变行为。这个对象看上去象是改变了它的类一样。状态模式把所研究的对象的行为包装在不同的状态对象里,每一个状态对象都属于一个抽象状态类的一个子类。状态模式的意图是让一个对象在其内部状态改变的时候,其行为也随之改变。状态模式需要对每一个系统可能取得的状态创立一个状态类的子类。当系统的状态变化时,系统便改变所选的子类。
结构
意图 允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
适用性
  • 一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。
  • 一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常, 有多个操作包含这一相同的条件结构。S t a t e模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。
Code Example
  1// State
  2
  3// Intent: "Allow an object to alter its behavior when its internal state 
  4// changes. The object will appear to change its class". 
  5
  6// For further information, read "Design Patterns", p305, Gamma et al.,
  7// Addison-Wesley, ISBN:0-201-63361-2
  8
  9/* Notes:
 10 * 
 11 * A finite state machine is an appropriate construct to use for a class whose
 12 * reaction to stimuli depends on previous behavior. In the past, each 
 13 * method in the class was coded as a switch statement, switching on the state. 
 14 * If a new state was added, then each method had to be edited. 
 15 * 
 16 * With the state design pattern, functionality specific to a state is placed 
 17 * in a helper class, and the main class delegates those methods that are 
 18 * state-specific to such helper classes.   
 19 * 
 20 */

 21 
 22namespace State_DesignPattern
 23{
 24    using System;
 25
 26    abstract class State 
 27    {
 28        protected string strStatename;        
 29
 30        abstract public void Pour();
 31        // do something state-specific here
 32    }

 33
 34    class OpenedState : State 
 35    {        
 36        public OpenedState ()
 37        {
 38            strStatename = "Opened";
 39        }

 40        override public void Pour()
 41        {
 42            Console.WriteLine("pouring");
 43            Console.WriteLine("pouring");
 44            Console.WriteLine("pouring");
 45        }

 46    }

 47    
 48    class ClosedState : State 
 49    {        
 50        public ClosedState()
 51        {
 52            strStatename = "Closed";
 53        }

 54        override public void Pour()
 55        {
 56            Console.WriteLine("ERROR - bottle is closed - cannot pour");
 57        }

 58    }

 59
 60    class ContextColaBottle 
 61    {
 62        public enum BottleStateSetting {
 63            Closed,
 64            Opened
 65        }
;
 66
 67        // If teh state classes had large amounts of instance data,
 68        // we could dynamically create them as needed - if this demo
 69        // they are tiny, so we just  create them as data members
 70        OpenedState openedState = new OpenedState();
 71        ClosedState closedState = new ClosedState();
 72
 73        public ContextColaBottle ()
 74        {
 75            // Initialize to closed
 76            CurrentState = closedState;
 77        }

 78
 79        private State CurrentState;
 80        
 81        public void SetState(BottleStateSetting newState)
 82        {
 83            if (newState == BottleStateSetting.Closed)
 84            {
 85                CurrentState = closedState;
 86            }

 87            else 
 88            {
 89                CurrentState = openedState;
 90            }

 91        }

 92
 93        public void Pour()
 94        {
 95            CurrentState.Pour();
 96        }
    
 97    }

 98
 99      /// <summary>
100    ///    Summary description for Client.
101    /// </summary>

102    public class Client
103    {
104        public static int Main(string[] args)
105        {
106            ContextColaBottle contextColaBottle = new ContextColaBottle();
107
108            Console.WriteLine("initial state is closed");
109
110            Console.WriteLine("Now trying to pour");
111              contextColaBottle.Pour();
112
113            Console.WriteLine("Open bottle");
114            contextColaBottle.SetState(ContextColaBottle.BottleStateSetting.Opened);
115
116            Console.WriteLine("Try to pour again");
117            contextColaBottle.Pour();
118
119            return 0;
120        }

121    }

122}

123
124