2012-11-12 10 views
8

bbv.Common.StateMachine klasa to najlepszy kod maszynowy stanu, jaki kiedykolwiek widziałem. Ale brakuje mu tylko jednej rzeczy: uzyskania aktualnego stanu.Jak uzyskać bieżący stan z klasy bbv.Common.StateMachine (teraz Appccelerate.StateMachine)?

Jest to system śledzenia zamówienie:

fsm = new ActiveStateMachine<States, Events>(); 

     fsm.In(States.OrderCreated) 
      .On(Events.Submitted) 
      .Goto(States.WaitingForApproval); 
     fsm.In(States.WaitingForApproval) 
      .On(Events.Reject) 
      .Goto(States.Rejected); 
     fsm.In(States.WaitingForApproval) 
      .On(Events.Approve) 
      .Goto(States.BeingProcessed); 
     fsm.In(States.BeingProcessed) 
      .On(Events.ProcessFinished) 
      .Goto(States.SentByMail); 
     fsm.In(States.SentByMail) 
      .On(Events.Deliver) 
      .Goto(States.Delivered); 

     fsm.Initialize(States.OrderCreated); 
     fsm.Start(); 
     fsm.Fire(Events.Submitted); 
     // Save this state to database 

Można zobaczyć, jak to działa łatwo.

Ale chcę zapisać stan zamówienia w bazie danych. Będę w stanie pokazać, w jakim stanie jest kolejność.

muszę metodę

fsm.GetCurrentState() 
//show this state in the a table 

. Właściwie jest sposób: mogę użyć ExecuteOnEntry i zmienić wartość lokalną na każdym wpisie stanu. Ale będzie kłopotliwe napisanie ExecuteOnEntry dla każdego stanu, ponieważ będę się powtarzać!

Musi to być delikatny sposób.

+1

Czy wiesz, że nazwa bbv.Common została zmieniona na Appccelerate. Sprawdź naszą nową stronę domową http://www.appccelerate.com –

Odpowiedz

13

Daniel wyjaśnił, jest to zgodne z projektem. Pozwól mi wyjaśnić, dlaczego:

Maszyna stanów umożliwia kolejkowanie zdarzeń. Dlatego pytanie maszyny stanu o jej aktualny stan może wprowadzać w błąd. Obecnie jest w stanie A, ale istnieje już kolejka zdarzeń, która sprawi, że stanie się to w stanie B.

Co więcej, uważam, że jest to zły projekt, aby połączyć wewnętrzne stany stanu maszyny (te, których używasz w swoim komputerze). definicja maszyny stanów) bezpośrednio ze stanami zewnętrznymi maszyny stanów (te, które chcesz zachować w bazie danych). Jeśli połączysz te dwie osoby bezpośrednio, tracisz możliwość wewnętrznego refaktoryzacji maszyny bez wpływu na zewnątrz (w twoim przypadku bazy danych). Często spotykam się ze scenariuszem, w którym muszę podzielić stan A na A1 i A2, ponieważ muszę dołączyć do nich różne działania, ale mimo to nadal reprezentują ten sam stan dla środowiska. Dlatego zdecydowanie radzę oddzielić stany wewnętrzne i zewnętrzne, tak jak napisano przy pomocy OnEntryExecute() lub przez podanie odwzorowania i użycie rozszerzenia. Jest to rozszerzenie, które będzie Ci aktualny stan:

public class CurrentStateExtension : ExtensionBase<State, Event> 
{ 
    public State CurrentState { get; private set; } 

    public override void SwitchedState(
     IStateMachineInformation<State, Event> stateMachine, 
     IState<State, Event> oldState, 
     IState<State, Event> newState) 
    { 
     this.CurrentState = newState.Id; 
    } 
} 

Możesz dodać rozszerzenie do machiny państwowej w ten sposób:

currentStateExtension = new CurrentStateExtension(); 
machine.AddExtension(currentStateExtension); 

Oczywiście można używać tego rozszerzenia bezpośrednio, aby uzyskać dostęp do obecnego stanu. Aby było jeszcze łatwiej, pozwól klasie, która definiuje automat stanów, zaimplementować rozszerzenie i przekazać je jako rozszerzenie.Pozwól się pozbyć dodatkowej klasy.

ostatnia uwaga: jeśli zapytać o bbv.Common (lub Appccelerate jak nazywa się teraz) w grupie google na https://groups.google.com/forum/?fromgroups#!forum/appccelerate, łatwiej jest mi znaleźć odpowiedź na pytanie i to ;-)

+0

Dzięki, spróbuję jak najszybciej. –

4

Jest to zgodne z projektem. Uważamy, że zapytanie o stan automatu stanów to zapach projektowy. Ale oczywiście są wyjątki. Dostępne są następujące dwie opcje:

  1. Użyj metod ExecuteOnEntry, aby zapisać stan zamówienia. Odzwierciedla to drogę, aby przejść, ponieważ nie chcesz przeciekać stany statemachine do swojej logiki biznesowej.
  2. Napisz własną maszynę do dekorowania stanów, która używa wewnętrznie StateMachine<TState, TEvent>. To naraża państwo.

Daniel

Powiązane problemy