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