2012-02-02 4 views
17

У меня есть довольно простые государственные потребности (на данный момент). Я думаю, что хотел бы смоделировать их с помощью api Stateless. (Но я не очень много знаю о государственных машин, так что я мог бы быть неправильно.)Базовая установка состояния машины с использованием состояния без учета состояния

Но я попасться в терминологии (В частности государственного и Trigger)

Вот Например: у меня есть класс заказа. Он настроен с несколькими состояниями. Они: новые, заполненные, отгруженные, завершенные, отмененные.

Несколько простых государственных правил, которые я хотел бы, чтобы эти государственные переходы разрешены:

  • Новый (по умолчанию)
  • New -> Заполненный
  • New -> Отменено
  • заливкой -> Доставка
  • Заполненный -> Отменено
  • Заполненный -> Доставка
  • Доставка -> Завершить

Итак, где я сработал, вот что такое «Триггер»?

Только в случае, если необходим более конкретный пример, скажем, я хочу способ, как это:

public bool UpdateOrderStatus(int OrderId, OrderStatusEnum NewOrderStatus) 

, который возвращает истину, если статус успешно обновлен. Как настроить и использовать Stateless, чтобы это произошло?

+3

Спасибо, что выкапывали безгражданство, я этого раньше не видел. – kenny

ответ

24

Станок имеет только одно состояние за раз; состояние, в котором оно находится в любом , указанное время называется текущим состоянием. Он может меняться от одного состояния к другому, когда инициировано событием триггера или условием, это , называемый переходным. from Finite-state machine on Wiki

Я считаю, триггер это запускающее событие.

Update:

, конечно, имя триггера иногда может быть равно некоторые из названий государств.

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

Update:

без гражданства действительно хорошая основа! Я попытался реализовать функциональность.

государства:

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; 
    } 
} 

Tester для класса 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

+0

@ Vaccano - Вы еще не указали свои триггеры для нас. Например, какое действие вызывает новый -> заполненный переход? Какое действие вызывает переходы New -> Canceled? Я считаю, что это будут ваши триггеры. Похоже, вы не говорите государственному аппарату, что переход состояния к выполнению. Вы просто определяете триггеры, которые вызывают переходы состояния, затем запускают триггеры по мере их возникновения, а конечный автомат выполняет переходы состояния. – mbeckish

+0

@mbeckish - Спасибо за ваш комментарий. Казалось бы, государственная машина не для меня. У меня будет вызов службы WCF, который запускает этот переход состояния. (т.е. 'ShipOrders (List orderIds)') Я не вижу, как это можно сделать в объекте. – Vaccano

Смежные вопросы