2012-02-02 116 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