Hi zusammen.
Hab vor kurzem eine Statemachine programmiert und mir dann ein paar
Gedanken dazu gemacht. Hier meine Ausführungen:
Sind Statemachines gut oder schlecht oder veraltet oder einfach nur eine
Art zu programmieren.
Wenn man Statemachines in C programmiert kann man das meines Wissens
nach mit nem Pointer, mit ner Variablen oder dem goto Befehl machen.
In jedem C-Buch ließt man allerdings, dass man den goto-Befehl vermeiden
soll. - Wegen der linearen Programmierung.
Die Herren Nassi und Shneiderman weisen darauf hin, dass Spaghetti-Code
total out ist und man nur einen Ein- und einen Ausgang pro
Funktionsblock haben soll.
Sind Statemachines jetzt nur für bestimmte Anwendungen sinnvoll? Wenn
ja, welche sind das? Kleine Programme wo nur bestimmte Zustände erreicht
werden können? Oder gibts auch mega-große Statemachines oder machen die
eben wieder keinen Sinn?
Würde mich freuen ein paar Meinungen zu hören.
Schönen Abend.
Eine state machine - oder auch Zustandsautomat - ist keine Art zu
programmieren, sondern ein Modell welches sich mathematisch exakt
formuliert ist.
Ob Du das in deinem Programm mit Pointern oder mit whatever
implementierst ist völlig egal.
In der Praxis eignet sich dies eher für kleinere Anwendungsfälle.
Versuch mal einen Zustandsautomaten für eine Aufzugsteuerung zu
entwickeln.
- Zwei Aufzüge
- 10 Stockwerke mit Tasten zum Holen des Aufzugs (jeweils nach unten und
nach oben)
- tasten für die Wahl der Stockwerke in den Aufzügen
- Aufzugtür offen/zu
- Position des Aufzugs
- Fahrtrichtung des Aufzugs
- usw. usw.
Da stößt Du recht schnell an die praktischen Grenzen, da die Anzahl der
möglichen Zustände schon sehr sehr groß wird.
> Versuch mal einen Zustandsautomaten für eine Aufzugsteuerung zu> entwickeln.
Ich denke, gerade für eine Aufzugssteuerung ist eine State-Maschine eine
sehr gute Lösung.
Das macht man dann aber nicht mehr per Hand, sondern mit professionellen
Werkzeugen, welche den C-Code für die State-Maschine aus einer
grafischen Darstellung für Dich generieren.
Diese Werkzeuge können meines Wissen nach eine Menge Tests an der
State-Maschine vornehmen, z.B, ob alle States besucht werden können,
oder ob es einen Zustand gibt, der nicht mehr verlassen werden kann.
Eine Steuerung für einen Aufzug ist hochgradig sicherheitsrelevant, Du
möchtest wahrscheinlich auch nicht aufgrund eines Software Fehlers darin
stecken bleiben.
Gerade deshalb werden in solchen Fällen geprüfte Code-Generatoren
eingesetzt werden, welche aus einer abstrakteren Darstellung, wie es
eine FSM ist, die effektive Steuerung generieren.
sicher nicht schrieb:
> In der Praxis eignet sich dies eher für kleinere Anwendungsfälle.
Ganz im Gegenteil.
Eine Statemachine ist ein ausgezeichnetes Mittel um komplette und
komplexe reale Maschinen in den Griff zu kriegen. Gerade die Aufteilung
in States und Übergänge der States unter bestimmten Umständen und die
gute Dokumentierbarkeit des Ganzen ist es, die Statemachines so
interessant machen.
sicher nicht schrieb:
> Da stößt Du recht schnell an die praktischen Grenzen, da die Anzahl der> möglichen Zustände schon sehr sehr groß wird.
Dann machst du was falsch.
Zb. sind in deiner Aufgabestellung die 10 Tasten für die Statemaschine
des Aufzugs ziemlich irrelevant. Ob es 10 oder 20 sind, ist egal, die
Statemaschine 'Aufzug' bekommt als Input 'Fahre zu Stockwerk x' und das
tut sie dann auch indem sie sich im Zustand 'Stehe in einem Stockwerk
und die Türen sind offen' diesen Fahrbefehl in ihre Queue der
anzufahrenden Ziele einsortiert. Der nächste Zustand ist dann 'Beginn
Tür schliessen', gefolgt von 'Tür geschlossen' gefolgt von 'Anfahren'
gefolgt von 'Anfahren nach oben' bzw. 'Anfahren nach unten' gefolgt von
'aufhören zu beschleunigen' gefolgt von 'beginn des Abbremsens vor dem
nächsten Ziel' gefolgt von 'ausrichten auf das Stockwerk' gefolgt von
'Tür öffnen anfangen' gefolgt von 'Tür ist offen' gefolgt von 'Stehe in
einem Stoclwerk und die Türen sind offen'.
Ob es weitere States gibt (vor allem der Fehlerfall ist immer
interessant) und wie die Aufteilung in States exakt funktioniert kann
von Aufzug zu Aufzug verschieden sein. Ob man die Logik, nach der das
nächste Fahrziel ausgewählt wird auch in eine Statemaschine quetscht
oder ob da irgendwelche Heuristiken angewendet werden oder KI oder
Zeitsteuerungen kann man von Fall zu Fall entscheiden. Das tangiert aber
die Statemaschine 'Aufzug' nicht. Die arbeitet stur ihren Stiefel
"Fahrbefehl ausführen" mit allem was dazu nötig ist ab.
Statemaschinen sind auch ein gutes Werkzeug um Multitasking Aufgaben
hinzukriegen. Gerade in Maschinen ist es oft so, dass ja mehrere
Vorgänge gleichzeitig ablaufen. Modelliert man jeden Vorgang mit einer
eigenen Statemaschine, die im Wechsel jeweils einen Zustand abarbeiten
dürfen, dann ergibt sich zwangsläufig eine Multitasking Struktur, selbst
wenn die Sprache dieses Konzept überhaupt nicht unterstützt (wie zb C)
und keinerlei dafür notwendige Konzepte zur Verfügung stellt.
alles State oder was schrieb:
> In jedem C-Buch ließt man allerdings, dass man den goto-Befehl vermeiden> soll. - Wegen der linearen Programmierung.
Nicht wegen irgendwelcher linearer Programmierung, sondern weil sonst
ganz schnell FORTRAN-Code daraus entsteht, den in zwei Jahren keiner
mehr pflegen kann.
Für bestimmte Ausnahmebehandlungen beispielsweise kann ein goto ein
nützliches Mittel sein, den Code übersichtlicher zu bekommen.
Allerdings würde ich es nicht als reguläre Methode zur Implementierung
einer state machine empfehlen, eben um Spaghetti-Code zu vermeiden.
> Die Herren Nassi und Shneiderman weisen darauf hin, dass Spaghetti-Code> total out ist und man nur einen Ein- und einen Ausgang pro> Funktionsblock haben soll.
Naja, solche Statements haben immer zwei Seiten: es ist was dran, man
kann natürlich durch wildes Anbringen von return-Anweisungen in einer
Funktion ein ähnliches Chaos produzieren wie mit einer planlosen
Ansammlung von gotos. Auch hier gilt aber: sinnvoll benutzt, ist es
ein nützliches Mittel, um die Übersichtlichkeit verbessern zu können.
Schau selbst: