henryjwr

See also: Other Geeks@INDC

State Design Pattern Maintain Flow of Algorithm Easily

In the book “Applying Domain-Driven Design and Patterns: With Examples in C# and .NET” by Jimmy Nielson he explain about State Design Pattern. He provide an example about state design pattern for Order transaction.

StateDiagram

This pattern is very nice, especially if you have a numerous transition flow in you problem. a beautiful about this pattern is eliminate hard coding of state transition and more flexible if you want to injected new state of it. combine with Strategy Design Pattern you could establish new state without brake the current implementation. imagine that you have already establishing a state flow in your code and suddenly the business process is change example from registered order could make invoice order and so on. With the helpfull of dependency injection and a little bit Strategy Pattern for your implementation you could achieve a better solution that doesn’t break OOD principle “Open/Close Principle” (A module should open for extension but closed for modification)

StatePatternCore

Above is 4GOF State Design Pattern.

   1: using System;
   2:  
   3: namespace ConsoleApplication1
   4: {
   5:     internal class SalesOrder
   6:     {
   7:         private IOrderState _currentState;
   8:         
   9:         public IOrderState OrderState
  10:         {
  11:             get { return _currentState; }
  12:             set { _currentState = value; }
  13:         }
  14:  
  15:         public string Id { get; set; }
  16:  
  17:         public SalesOrder(String id)
  18:         {
  19:             this.Id = id;
  20:             _currentState = new NewOrder(this);
  21:             
  22:         }
  23:  
  24:         public void RegisterOrder()
  25:         {
  26:             Console.WriteLine("Start Registering, Order Id: " + this.Id);
  27:             _currentState.Register();
  28:         }
  29:  
  30:         public void AddOrderLine()
  31:         {
  32:             Console.WriteLine("Start Add Order Line, Order Id: " + this.Id);
  33:             _currentState.AddOrderLine();
  34:         }
  35:  
  36:         public void Cancel()
  37:         {
  38:             Console.WriteLine("Start canceling, Order Id: " + this.Id);
  39:             _currentState.Cancel();
  40:         }
  41:     }
  42:     internal interface IOrderState
  43:     {
  44:         SalesOrder Order{ get; set;}
  45:         void AddOrderLine();
  46:         void Register();
  47:         void Ship();
  48:         void Cancel();
  49:         void Invoice();
  50:         void Grant();
  51:     }
  52:  
  53:  
  54:     internal class NewOrder : IOrderState 
  55:     {
  56:         public NewOrder():this(null){}
  57:  
  58:         public NewOrder(SalesOrder salesOrder)
  59:         {
  60:            this.Order = salesOrder;
  61:            Console.WriteLine("Order Id :" + Order.Id + " has taken order");
  62:         }
  63:  
  64:         #region Implementation of IOrderState
  65:  
  66:         public SalesOrder Order { get; set; }
  67:  
  68:         public void AddOrderLine()
  69:         {
  70:             Console.WriteLine("Order Id: " + Order.Id + " Do Add Order Line");
  71:             Order.OrderState = new NewOrder(Order);
  72:         }
  73:  
  74:         public void Register()
  75:         {
  76:             Console.WriteLine("Order Id: " + Order.Id + " Do Registering");
  77:             Order.OrderState = new Registered(Order);
  78:         }
  79:  
  80:         public void Ship()
  81:         {
  82:             throw new System.NotImplementedException();
  83:         }
  84:  
  85:         public void Cancel()
  86:         {
  87:             Console.WriteLine("Order Id: " + Order.Id + " Do cancel");
  88:             Order.OrderState = new Cancelled(Order);
  89:         }
  90:  
  91:         public void Invoice()
  92:         {
  93:             throw new System.NotImplementedException();
  94:         }
  95:  
  96:         public void Grant()
  97:         {
  98:             throw new System.NotImplementedException();
  99:         }
 100:  
 101:         #endregion
 102:     }
 103:  
 104:     internal class Registered : IOrderState
 105:     {
 106:         
 107:         public Registered(SalesOrder order)
 108:         {
 109:             this.Order = order;
 110:             Console.WriteLine("Order Id :" + Order.Id + " has been registered");
 111:         }
 112:  
 113:         #region Implementation of IOrderState
 114:  
 115:         public SalesOrder Order { get; set; }
 116:  
 117:         public void AddOrderLine()
 118:         {
 119:             Console.WriteLine("Order Id: " + Order.Id + " Do Add Order Line");
 120:             Order.OrderState = new NewOrder(Order);
 121:         }
 122:  
 123:         public void Register()
 124:         {
 125:             throw new System.NotImplementedException();
 126:         }
 127:  
 128:         public void Ship()
 129:         {
 130:             throw new System.NotImplementedException();
 131:         }
 132:  
 133:         public void Cancel()
 134:         {
 135:             Console.WriteLine("Order Id: " + Order.Id + " Do cancel");
 136:             Order.OrderState = new Cancelled(Order);
 137:         }
 138:  
 139:         public void Invoice()
 140:         {
 141:             throw new System.NotImplementedException();
 142:         }
 143:  
 144:         public void Grant()
 145:         {
 146:             throw new System.NotImplementedException();
 147:         }
 148:  
 149:         #endregion
 150:     }
 151:  
 152:     internal class Cancelled : IOrderState
 153:     {
 154:         public Cancelled(SalesOrder order)
 155:         {
 156:             
 157:             this.Order = order;
 158:             Console.WriteLine("Order Id: " + Order.Id + " Has been Cancelled");
 159:         }
 160:  
 161:         #region Implementation of IOrderState
 162:  
 163:         public SalesOrder Order { get; set; }
 164:  
 165:         public void AddOrderLine()
 166:         {
 167:             Console.WriteLine("Order Id " + Order.Id + " has been cancel please create new order");
 168:         }
 169:  
 170:         public void Register()
 171:         {
 172:             Console.WriteLine("Order Id " + Order.Id + " has been cancel please create new order");
 173:         }
 174:  
 175:         public void Ship()
 176:         {
 177:             Console.WriteLine("Order Id " + Order.Id + " has been cancel please create new order");
 178:         }
 179:  
 180:         public void Cancel()
 181:         {
 182:             Console.WriteLine("Order Id " + Order.Id + " has been cancel please create new order");
 183:         }
 184:  
 185:         public void Invoice()
 186:         {
 187:             Console.WriteLine("Order Id " + Order.Id + " has been cancel please create new order");
 188:         }
 189:  
 190:         public void Grant()
 191:         {
 192:             Console.WriteLine("Order Id " + Order.Id + " has been cancel please create new order");
 193:         }
 194:  
 195:         #endregion
 196:     }
 197:     
 198: }

The different betwen State Pattern and Strategy pattern are Strategy is more dynamic behaviour rather than State, so the state flow is determine by mapping behavior within | by its context. In other word State Pattern are use when we want to mapping already have state flow, on the other hand Strategy Pattern could manypulaterd the state of implementation using injection.

Share this post: | | | |

Comments

No Comments