2012-02-02 109 views
17

我有一些相當簡單的狀態需求(現在)。我想我想用Stateless API對這些模型進行建模。 (但我真的不知道很多關於狀態機,所以我可能是錯的。)使用無狀態的基本狀態機設置

但在術語(具體國家觸發

這裏是我被逮住例如:我有一個訂單類。它設置了幾個州。它們是:新建,填充,運輸,已完成,已取消。

一些簡單的狀態的規則,我想的是,這些狀態轉換是被允許:

  • 新(默認設置)
  • 新 - 填充
  • 新建> - >取消
  • 填充的 - >航運
  • 填充 - >取消
  • 填充 - >航運
  • 航運 - >完成

所以,我在這裏被絆倒的是什麼是我的「觸發器」?

以防萬一需要更具體的例子,說我想要一個方法是這樣的:

public bool UpdateOrderStatus(int OrderId, OrderStatusEnum NewOrderStatus) 

如果狀態更新成功,將返回true。如何設置和使用無狀態來實現這一點?

+3

感謝您挖掘無狀態,我之前沒有見過。 – kenny 2012-02-02 18:48:47

回答

24

機器一次只處於一種狀態;它在任何時間的狀態 被稱爲當前狀態。當由觸發事件或條件啓動時,它可以從一個狀態 變爲另一個狀態,這是 稱爲轉換。 from Finite-state machine on Wiki

我相信,觸發此觸發事件

更新:

當然觸發器名字有時會等於某個國家的名字。

New (initial state) 
New -> Filled (trigger "Filled") 
New -> Cancelled (trigger "Cancelled") 
Filled -> Shipping (trigger "ToBeShipped") 
Filled -> Cancelled (trigger "Cancelled") 
Shipping -> Complete (trigger "Completed"). 

更新:

無狀態是非常好的框架! 我試過實現這個功能。

國:

public enum State 
{ 
    New, 
    Filled, 
    Shipping, 
    Cancelled, 
    Completed 
} 

觸發器:

public enum Trigger 
{ 
    Filled, 
    Cancelled, 
    ToBeShipped, 
    Completed 
} 

Order類:

public class Order 
{ 
    private readonly StateMachine<State, Trigger> _stateMachine; 

    public Order() 
    { 
     _stateMachine = CreateStateMachine(); 
    } 

    public bool TryUpdateOrderStatus(Trigger trigger) 
    { 
     if (!_stateMachine.CanFire(trigger)) 
      return false; 

     _stateMachine.Fire(trigger); 
     return true; 
    } 

    public State Status 
    { 
     get 
     { 
      return _stateMachine.State; 
     } 
    } 

    private StateMachine<State, Trigger> CreateStateMachine() 
    { 
     StateMachine<State, Trigger> stateMachine = new StateMachine<State, Trigger>(State.New); 
     stateMachine.Configure(State.New) 
      .Permit(Trigger.Filled, State.Filled) 
      .Permit(Trigger.Cancelled, State.Cancelled); 

     stateMachine.Configure(State.Filled) 
      .Permit(Trigger.ToBeShipped, State.Shipping) 
      .Permit(Trigger.Cancelled, State.Cancelled); 

     stateMachine.Configure(State.Shipping) 
      .Permit(Trigger.Completed, State.Completed); 

     stateMachine.OnUnhandledTrigger((state, trigger) => 
      { 
       Console.WriteLine("Unhandled: '{0}' state, '{1}' trigger!"); 
      }); 
     return stateMachine; 
    } 
} 

測試儀Order類:

Order order = new Order(); 
bool result = order.TryUpdateOrderStatus(Trigger.Completed); 
Console.WriteLine("Attemp to complete order: {0}", result); 
Console.WriteLine("Order status: {0}", order.Status); 

result = order.TryUpdateOrderStatus(Trigger.ToBeShipped); 
Console.WriteLine("Attemp to ship order: {0}", result); 
Console.WriteLine("Order status: {0}", order.Status); 

result = order.TryUpdateOrderStatus(Trigger.Cancelled); 
Console.WriteLine("Attemp to cancel order: {0}", result); 
Console.WriteLine("Order status: {0}", order.Status); 
+0

沒錯,但是在我上面的情況下,它是如何工作的? – Vaccano 2012-02-02 18:17:37

+0

@Vaccano - 你還沒有爲我們列出你的觸發器。例如,導致新建 - >填充轉換的操作是什麼?什麼行動導致新的 - >取消的轉換?我相信那些會成爲你的觸發器。它看起來像你不告訴狀態機執行哪種狀態轉換。您只需定義導致狀態轉換的觸發器,然後觸發發生的觸發器,狀態機將執行狀態轉換。 – mbeckish 2012-02-02 18:20:45

+0

@mbeckish - 感謝您的評論。這似乎是一個狀態機不適合我。我將有一個WCF服務調用來觸發這個狀態轉換。 (即'ShipOrders(列表 orderIds)')我不明白怎麼做成一個對象。 – Vaccano 2012-02-02 18:24:39