2012-02-02 29 views
17

Tôi có một số yêu cầu trạng thái khá đơn giản (hiện tại). Tôi nghĩ rằng tôi muốn mô hình hóa chúng bằng cách sử dụng api Stateless. (Nhưng tôi không thực sự biết nhiều về máy nhà nước, vì vậy tôi có thể là sai.)Thiết lập Máy Trạng thái Cơ bản bằng cách sử dụng Stateless

Nhưng tôi đang nhận được đánh bắt lên trong thuật ngữ (Cụ thể Nhà nướcKích hoạt)

Dưới đây là một Ví dụ: Tôi có một lớp đơn đặt hàng. Nó được thiết lập với một vài trạng thái. Đó là: Mới, Đầy, Giao hàng, Đã hoàn thành, Đã hủy.

Một vài quy tắc nhà nước đơn giản tôi muốn là những hiệu ứng chuyển tiếp trạng thái được phép:

  • mới (là mặc định)
  • New -> Đầy
  • New -> hủy
  • Tô nền -> Vận chuyển
  • Đã điền -> Đã hủy
  • Đã điền -> Vận chuyển
  • Vận chuyển -> Hoàn thành

Vì vậy, nơi tôi bị vấp ngã ở đây là "Trình kích hoạt" của tôi là gì?

Chỉ trong trường hợp một ví dụ cụ thể hơn là cần thiết, nói rằng tôi muốn có một phương pháp như thế này:

public bool UpdateOrderStatus(int OrderId, OrderStatusEnum NewOrderStatus) 

rằng sẽ trở thành sự thật nếu tình trạng cập nhật thành công. Làm thế nào có thể thiết lập và sử dụng Stateless để thực hiện điều này?

+3

Cảm ơn bạn đã đào bới Stateless, tôi chưa từng thấy điều đó trước đây. – kenny

Trả lời

24

Máy chỉ ở một trạng thái tại một thời điểm; trạng thái tại thời điểm bất kỳ được gọi là trạng thái hiện tại. Nó có thể thay đổi từ một trạng thái sang một trạng thái khác khi được bắt đầu bởi sự kiện kích hoạt hoặc điều kiện, đây là được gọi là chuyển đổi. from Finite-state machine on Wiki

Tôi tin rằng, cò là này kích hoạt sự kiện.

Cập nhật:

Trong số tên cò nhiên đôi khi có thể tương đương với một số tên tuổi nhà nước.

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

Cập nhật:

stateless là khuôn khổ thực sự tốt đẹp! Tôi đã cố triển khai chức năng này.

Hoa:

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

Triggers:

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

lớp theo thứ tự:

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 cho các lớp học theo thứ tự:

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

Phải, nhưng nó hoạt động như thế nào trong kịch bản của tôi ở trên? – Vaccano

+0

@Vaccano - Bạn chưa liệt kê trình kích hoạt của bạn cho chúng tôi. Ví dụ: hành động nào gây ra chuyển đổi Mới -> Đã thực hiện? Hành động nào gây ra chuyển đổi Mới -> Đã bị hủy? Tôi tin rằng những người đó sẽ là những người khởi xướng của bạn. Có vẻ như bạn không nói cho máy trạng thái biết trạng thái chuyển đổi cần thực hiện. Bạn chỉ cần xác định các trigger gây ra quá trình chuyển trạng thái, sau đó kích hoạt các trigger khi chúng xảy ra, và máy trạng thái sẽ thực hiện các chuyển trạng thái. – mbeckish

+0

@mbeckish - Cảm ơn nhận xét của bạn. Có vẻ như một cỗ máy nhà nước không dành cho tôi. Tôi sẽ có một cuộc gọi dịch vụ WCF bắn chuyển tiếp trạng thái này. (tức là 'ShipOrders (Danh sách orderIds)') Tôi không thấy làm thế nào mà có thể được thực hiện thành một đối tượng. – Vaccano

Các vấn đề liên quan