Einzelnen Beitrag anzeigen

Benutzerbild von Vis
Vis

Registriert seit: 26. Apr 2013
26 Beiträge
 
Delphi XE8 Professional
 
#13

AW: Stateless - StateMachine für Delphi

  Alt 20. Jan 2016, 13:05
Hallo zusammen, ich muss jetzt mal bei euch nachhaken bezüglich State Machines. So ganz steige ich noch nicht durch. Klassischerweise gibt es doch Aktionen/Actions die bei einem Zustandsübergang ausgeführt werden. Werden diese bei Stateless im Guard ausgeführt? Oder im OnEntry Ereignis? Oder eher als PermitDynamic, wenn ausgewertet werden muss ob die Aktion erfolgreich war? Oder bin ich auf dem falschen weg?

Da ich oft Benutzereingaben verarbeiten muss, habe ich eine kurze Testanwendung erstellt, in der der Text eines Edit-Feldes genutzt wird um Daten aus einer Datenbank zu holen. Ein paar Zustandsdiagramme von mir im Anhang.
Als ersten Ansatz, kann vom Zustand "Idle" nur in den Zustand "DatenErhalten" gewechselt werden, wenn die Daten aus der Datenbank erfolgreich gelesen wurden (dies geschieht im Guard)

Delphi-Quellcode:
TState = (Idle, DatenErhalten, DatenErhaltenError, DatenAbrufen);
TTrigger = (Tabulator, Next, Error);
TSM = TStateMachine<TState, TTrigger>;
Delphi-Quellcode:
 
SM := TSM.Create(TState.Idle);

SM.Configure(TState.Idle)
 .PermitIf(TTrigger.Tabulator, TState.DatenErhalten, GuardGetDataFromDatabase);

Andererseits könnte man stattdessen noch einer Fehlerzustand hinzufügen "DatenErhaltenError" und mit einem PermitDynamic verzweigen:
Delphi-Quellcode:
SM.Configure(TState.Idle)
    .PermitDynamic(TTrigger.Tabulator,
    function: TState
    begin
      if GetDataFromDatabase(edt1.Text)
      then
        Result := TState.DatenErhalten
      else
        Result := TState.DatenErhaltenError;
    end);
Oder ist es vielleicht schlauer noch einen Zwischenstate einzufügen "DatenAbrufen" und in dessen OnEntry überprüfen ob der Datenabruf erfolgreich war:
Delphi-Quellcode:
 
SM.Configure(TState.Idle)
    .Permit(TTrigger.Tabulator, TState.DatenAbrufen);

SM.Configure(TState.DatenAbrufen)
    .OnEntry(
      procedure
      begin
        if GetDataFromDatabase(edt1.Text) then
          //...
        else
          //...
      end);
Über Hilfe oder ein paar Gedankenanstöße wäre ich dankbar.

Grüße
Miniaturansicht angehängter Grafiken
diagramm1.png   diagramm2.png   diagramm3.png  
  Mit Zitat antworten Zitat