Forum: Compiler & IDEs Euer Statement zur Statemachine


von alles State oder was (Gast)


Lesenswert?

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.

von sicher nicht (Gast)


Lesenswert?

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.

von Klaus F. (kfalser)


Lesenswert?

> 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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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:
1
bool func(int a, int b)
2
{
3
    bool error = true;
4
5
    if (early_error) {
6
        /* cannot continue here */
7
        error = false;
8
    } else {
9
        if (!do_something(a, b)) {
10
            /* another error happened */
11
            error = false;
12
        } else {
13
            if (do_something_else(a, b) < limit) {
14
            /* out of limits */
15
                error = false;
16
            } else {
17
                do_even_more(a, b);
18
            }
19
        }
20
    }
21
    return error;
22
}
1
bool func(int a, int b)
2
{
3
    if (early_error) {
4
        /* cannot continue here */
5
        return false;
6
7
    if (!do_something(a, b)) {
8
        /* another error happened */
9
        return false;
10
11
    if (do_something_else(a, b) < limit)
12
        /* out of limits */
13
        return false;
14
15
    do_even_more(a, b);
16
17
    return true;
18
}

Welche Implementierung kann man besser lesen?

von Sachich N. (dude) Benutzerseite


Lesenswert?


Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.