Zustandsdiagramme

Die UML-Zustandsdiagramme gehen auf die von David Harel in den 1980er Jahren entwickelten Zustandsautomaten zurück.

Bei den Basiskonzepten haben Sie gelernt, dass Objekte Zustände besitzen. Das UML-Zustandsdiagramm ist ein Ausdrucksmittel, welches immer dann angewendet werden sollte, wenn im Mittelpunkt der Betrachtung ein komplexes zustandsorientiertes Problem steht. Des Weiteren ist die softwareseitige Implementation einer Zustandsmaschine nicht trivial. SiSy ist in der Lage, aus dem UML-Zustandsdiagramm den entsprechenden Quellcode zu generieren. Die automatisch generierte Zustandsmaschine verringert den Aufwand und reduziert die Fehleranfälligkeit gegenüber einer manuellen Implementation enorm. Zustandsmaschinen sind oft zyklisch und laufen, solange ein Objekt existiert. Die Zustandsänderungen sind in der Regel an Ereignisse und Bedingungen geknüpft. Das Zustandsdiagramm zeigt nur Zustände und Zustandswechsel eines Objektes, jedoch keine objektübergreifenden Sachverhalte. Ein Objekt kann aber durchaus mehrere Zustandsmaschinen gleichzeitig, also parallel, besitzen.

Zustandsdiagramme zeigen mögliche Zustände und Zustandswechsel eines Objektes.

Das folgende Zustandsdiagramm zeigt, welchen Zustand und welche Zustandswechsel ein Objekt mindestens hat, auch ohne eine explizit realisierte Zustandsmaschine.

Die wichtigsten Modellierungselemente des Zustandsdiagramms sind:

  • Zustände
  • Zustandsübergänge
  • Pseudozustände: Startknoten, Endknoten
  • Zustandsaktionen: entry, do, exit

Zustände

Ein Objektzustand repräsentiert zu einem oder mehreren determinierten, konkreten Eigenschaftswerten (Zustandsattribute) zuordenbares Verhalten (Aktivitäten). Die dem Zustand zuordenbaren Aktivitätstypen sind zum Beispiel:

  • entry, einmaliges Verhalten beim Einnehmen des Zustandes
  • do, wiederholtes Verhalten während des Zustandes
  • exit, einmaliges Verhalten beim Verlassen des Zustandes

Die Notation von Zuständen erfolgt wie bei Aktion und Aktivität als Rechteck mit abgerundeten Ecken. Zusätzlich ist es üblich, den Zustand detailliert darzustellen. Ähnlich wie bei der Klasse wird das Zustandssymbol unterteilt und es können zustandsbestimmende Attribute und Aktionen angegeben werden. Wichtig ist, dass ein Zustand nicht als etwas statisches angesehen wird. Ein Objekt führt, während es sich in einem Zustand befindet, auch immer das dem Zustand zugeordnete Verhalten aus. Deshalb ist es üblich, die Zustandsaktivitäten auch mit zu modellieren.

Pseudozustände

inital node, Startknoten

Der Startknoten repräsentiert in nicht hierarchisierten Zustandsdiagrammen im einfachsten Fall den Zustand bevor das Objekt existiert. Zweckmäßigerweise sollte immer nur eine ausgehende Kante modelliert werden. Die Notation des Startknotens ist ein kleiner, ausgefüllter Kreis.

final node, Endknoten

Ein Endknoten repräsentiert in einer einfachen Zustandsmaschine den Zustand nach dem das Objekt zerstört wurde. Es ist möglich und auch üblich Zustandsmaschinen als endlose zyklische Automaten zu modellieren. In diesem Fall wird das Zerstören des Objektes nicht modelliert und der Endknoten fehlt in der Darstellung. Die Notation des Endknotens ist ein kleiner ausgefüllter Kreis im Kreis.

Zustandsübergänge

transition, Zustandsübergang

Der Übergang von einem Zustand in den anderen bedeutet in jedem Fall Verhalten. Es passiert also etwas und der Übergang verbraucht auch Zeit. Es wird konkretes Verhalten ausgeführt und damit finden wir die Zustandsübergänge im Programmcode als eine entsprechende Codesequenz. Die Zustandsübergänge können durch Ereignisse und Bedingungen ausgelöst werden. Das Ereignis spezifiziert wann der Übergang stattfindet. Letztlich ist ein Ereignis im Quellcode eine Operation der Klasse des Objektes. In eingebetteten Systemen kann das auch eine dem Objekt zugeordnete Interruptserviceroutine (ISR) sein. Bedingungen (Guards) drücken aus, unter welchen Konditionen ein Übergang zulässig ist. Die Notation von Zustandsübergängen erfolgt durch eine gerichtete Linie (Pfeil) mit Beschriftung (Ereignis [Bedingung] / Aktion).

Mit dem Zustandsdiagramm in SiSy programmieren

SiSy ist in der Lage, aus solchen Zustandsdiagrammen den kompletten Quellcode, der die Zustandsmaschine realisiert, zu generieren und in die zugehörige Klasse einzubetten. Bei der folgenden Aufgabe soll eine Menge von Bällen über ein Spielfeld rollen und bei jeder Berührung Ihren Zustand ändern. Der jeweilige Zustand ist durch eine entsprechende Farbe des Balls anzuzeigen. Führen Sie zur Vorbereitung des Projektes folgende Schritte aus:

  1. Projekt „Beispiel_SM“ anlegen
  2. aktuelle SVL aus dem LibStore laden
  3. Klassendiagramm anlegen
  4. Klassendiagramm öffnen und die Vorlage „Grundgerüst SVL GAME Application“

Jetzt muss der Ball konstruiert werden. Näheres zum angewendeten Programmierkonzept erfahren Sie im Abschnitt zum SVL Game Framework. Ein Ball soll folgende Merkmale besitzen:

  1. selbständige Bewegung, AutoMovedElement
  2. am Spielfeldrand abprallen, OnBorder_BounceBack
  3. ist ein mittelgroßer Kreis, Show_AsEllipse, Start_UserSize
  4. beim Start zufällige Position, Richtung, Geschwindigkeit Start_PositionRandom, Start_DirectionRandom, Speed_Random
  5. an andeen Bällen abprallen, OnHit_BounceBack
  6. es sollen zehn Bälle existieren

Diese Lösung können wir jetzt schon mal übersetzen und testen. Es sollten jetzt zehn Bälle mit unterschiedlicher Richtung und Geschwindigkeit über das Spielfeld wuseln.

Als Nächstes benötigen wir ein „Ereignis“ für die Zustandswechsel. Was in der Zustandsmaschine als Ereignis erscheint ist im Klassendiagramm eine Operation, im konkreten Fall der Event-Handler für das Ereignis onHit. Es ist nötig diese virtuelle Operation der Basisklasse (bzw. Basistemplate) in der Klasse Ball zu überschreiben.

Damit das Ereignis im Zustandsdiagramm sichtbar wird notieren wir im Eingabefeld der Zusicherung den folgenden Ausdruck:

sm::onHit

Damit haben wir dem Werkzeug mitgeteielt, dass diese Operation im Zustandsdiagramm (state machine) mit dem Alias onHit angezeigt wird.

Die Zustandsmaschine selbst bauen wir, indem der Klasse Ball ein Element vom Typ Zustandsattribut zugewiesen wird. Ziehen Sie dieses Element aus der Objektbibliothek und fügen Sie es in die Klasse Ball ein. Geben Sie dem Zustandsattribut einen Namen. Der Einfachheit halber zum Beispiel „zustand“. Falls es mehrere parallele Zustandsmaschinen in einer Klasse gibt sollte der Name entsprechend signifikant sein.

Öffnen Sie das Zustandsdiagramm indem Sie auf dem Zustandsattribut „nach unten“ gehen. Laden sie aus dem LibStore die Vorlage für eine Zustandsmaschine mit vier Zuständen.

Sie erhalten eine Grundstruktur für Ihre Zustandsmaschine mit vier aufeinander folgenden Zuständen. Jeder zustand verfügt bereits über eine Aktion vom Typ entry. Diese Vorlage können Sie jetzt auf Ihre Lösung anpassen bzw. abändern.

Im ersten Schritt geben wir den Zuständen andere Namen und notieren bei den Aktionen was passieren soll. Beachten Sie, dass die Namen der Zustande konform mit der verwendeten Programmiersprache sind. Für C++ bedeutet das: keine Sonderzeichen, keine Umlaute, keine Leerzeichen.

Als nächstes modellieren wir die Zustandsübergänge. Jetzt kommt unser Ereignis onHit ins Spiel. Wählen sie im Dialog „Definieren“ auf den Kanten das Ereignis onHit für die Zustandsübergänge.

Jetzt können sie die Programmbefehle für die Zustandsaktionen notieren. Ergänzen Sie die einzelnen Aktionen vom Typ entry mit den folgenden C++ Anweisungen.

withe::entry / farbe = weiß
 color=RGB(255,255,255); 
red::entry / farbe = rot
 color=RGB(255,0,0); 
yellow::entry / farbe = gelb
 color=Color::Yellow; 
green::entry / farbe = grün
 color=Color::Green; 

Das war es eigentlich auch schon. Wir haben eine Zustandsmaschine mit den vier Zuständen white, red, yellow und green konstruiert. Die Zustandsübergänge erfolgen auf das ereignis onHit. Beim Eintritt in den jeweiligen Zustand erfolgt der Farbwechsel.

Jetzt können wir die Lösung testen. gehen Sie „nach oben“ zurück in das Klassendiagramm. Übersetzten und starten Sie das Programm. Der Test sollte folgendes Bild zeigen.

Viel Spaß beim Testen und Weiterentwickeln!

Videozusammenfassung

Weiterführendes