允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
名称 |
State |
结构 |
![](/images/cnblogs_com/darkangel/State.gif) |
意图 |
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。 |
适用性 |
- 一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。
- 一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常, 有多个操作包含这一相同的条件结构。S t a t e模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。
|
Code Example |
1 // State 2![](/Images/OutliningIndicators/None.gif) 3 // Intent: "Allow an object to alter its behavior when its internal state 4 // changes. The object will appear to change its class". 5![](/Images/OutliningIndicators/None.gif) 6 // For further information, read "Design Patterns", p305, Gamma et al., 7 // Addison-Wesley, ISBN:0-201-63361-2 8![](/Images/OutliningIndicators/None.gif) 9![](/Images/OutliningIndicators/ExpandedBlockStart.gif) /**//* 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 22 namespace State_DesignPattern 23![](/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](/Images/OutliningIndicators/ContractedBlock.gif) { 24 using System; 25![](/Images/OutliningIndicators/InBlock.gif) 26 abstract class State 27![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 28 protected string strStatename; 29![](/Images/OutliningIndicators/InBlock.gif) 30 abstract public void Pour(); 31 // do something state-specific here 32 } 33![](/Images/OutliningIndicators/InBlock.gif) 34 class OpenedState : State 35![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 36 public OpenedState () 37![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 38 strStatename = "Opened"; 39 } 40 override public void Pour() 41![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 42 Console.WriteLine(" pouring "); 43 Console.WriteLine(" pouring "); 44 Console.WriteLine(" pouring "); 45 } 46 } 47 48 class ClosedState : State 49![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 50 public ClosedState() 51![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 52 strStatename = "Closed"; 53 } 54 override public void Pour() 55![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 56 Console.WriteLine("ERROR - bottle is closed - cannot pour"); 57 } 58 } 59![](/Images/OutliningIndicators/InBlock.gif) 60 class ContextColaBottle 61![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 62![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) public enum BottleStateSetting { 63 Closed, 64 Opened 65 }; 66![](/Images/OutliningIndicators/InBlock.gif) 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![](/Images/OutliningIndicators/InBlock.gif) 73 public ContextColaBottle () 74![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 75 // Initialize to closed 76 CurrentState = closedState; 77 } 78![](/Images/OutliningIndicators/InBlock.gif) 79 private State CurrentState; 80 81 public void SetState(BottleStateSetting newState) 82![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 83 if (newState == BottleStateSetting.Closed) 84![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 85 CurrentState = closedState; 86 } 87 else 88![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 89 CurrentState = openedState; 90 } 91 } 92![](/Images/OutliningIndicators/InBlock.gif) 93 public void Pour() 94![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 95 CurrentState.Pour(); 96 } 97 } 98![](/Images/OutliningIndicators/InBlock.gif) 99![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) /**//// <summary> 100 /// Summary description for Client. 101 /// </summary> 102 public class Client 103![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 104 public static int Main(string[] args) 105![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 106 ContextColaBottle contextColaBottle = new ContextColaBottle(); 107![](/Images/OutliningIndicators/InBlock.gif) 108 Console.WriteLine("initial state is closed"); 109![](/Images/OutliningIndicators/InBlock.gif) 110 Console.WriteLine("Now trying to pour"); 111 contextColaBottle.Pour(); 112![](/Images/OutliningIndicators/InBlock.gif) 113 Console.WriteLine("Open bottle"); 114 contextColaBottle.SetState(ContextColaBottle.BottleStateSetting.Opened); 115![](/Images/OutliningIndicators/InBlock.gif) 116 Console.WriteLine("Try to pour again"); 117 contextColaBottle.Pour(); 118![](/Images/OutliningIndicators/InBlock.gif) 119 return 0; 120 } 121 } 122 } 123![](/Images/OutliningIndicators/None.gif) 124![](/Images/OutliningIndicators/None.gif) |