Agile Modellierung mit
UML
Loading

3.4 Statecharts

Statecharts sind eine Weiterentwicklung der Automaten zur Beschreibung von Objektverhalten. Jedes komplexere System besitzt steuernde und kontrollierende Anteile, die mit Statecharts modelliert werden können. Die hier vorgestellte Variante der Statecharts nutzt die OCL als Bedingungssprache und Java-Anweisungen als Aktionen.

3.4.1 Eigenschaften von Statecharts

Automaten gibt es in unterschiedlichsten Ausprägungen. So können Automaten ausführbar sein, zur Erkennung von Sequenzen von Buchstaben oder Nachrichten, zur Beschreibung des Zustandsraums eines Objekts oder zur Spezifikation von Antwortverhalten auf einen Stimulus genutzt werden. Der Übersichtsartikel [vdB94] zeigt, dass es für Statecharts eine Reihe syntaktischer Varianten und semantischer Interpretationsmöglichkeiten gibt, die den jeweiligen Anwendungsgebieten angepasst sind. Die Statecharts der UML/P lassen sich durch Steuerung mit geeigneten Stereotypen für die Modellierung, Codegenerierung oder Testfallbeschreibung einsetzen. Abbildung 3.29 zeigt ein Statechart, das eine vereinfachende Abstraktion des Zustandssystems einer Auktion darstellt. Abbildung 3.30 beinhaltet eine überlappende Liste von Aufgaben, die ein Statechart übernehmen kann.


Abbildung 3.29: Statechart

Die (überlappenden) Aufgaben eines Statecharts können sein:
  • Darstellung des Lebenszyklus eines Objekts
  • Implementierungsbeschreibung einer Methode
  • Implementierungsbeschreibung des Verhaltens eines Objekts
  • Abstrakte Anforderungsbeschreibung an den Zustandsraum eines Objekts
  • Darstellung der Reihenfolge von erlaubten Eintreten von Stimuli (Aufrufreihenfolge)
  • Charakterisierung der möglichen oder erlaubten Verhalten eines Objekts
  • Bindeglied zwischen Zustands- und Verhaltensbeschreibung
Abbildung 3.30: Aufgabenvielfalt eines Statecharts

Eine kompakte Übersicht der Statechart-Konstrukte ist in den Abbildungen 3.31, 3.32 und 3.33 zusammengefasst.

Zustand
Ein Zustand (synonym: Diagrammzustand) repräsentiert eine Teilmenge der möglichen Objektzustände. Ein Diagrammzustand wird durch einen Zustandsnamen und je einer optionalen Zustandsinvariante, entry-Aktion, exit-Aktion und do-Aktivität modelliert.
Startzustand
In einem Startzustand beginnen Objekte ihren Lebenszyklus. Mehrere Startzustände erlauben mehrere Arten der Objekterzeugung darzustellen. Die Bedeutung eines Startzustands als Teil eines anderen Zustands ist in Abschnitt 5.4.2, Band 1 beschrieben.
Endzustand
Ein Endzustand beschreibt, dass das Objekt in diesem Zustand seine Pflicht erfüllt hat und nicht mehr gebraucht wird. Allerdings können Endzustände wieder verlassen werden. Die Bedeutung eines Endzustands als Teil eines anderen Zustands ist in Abschnitt 5.4.2, Band 1 beschrieben.
Teilzustand
Zustände können hierarchisch geschachtelt werden. Ein Gesamtzustand enthält mehrere Teilzustände.
Zustandsinvariante
ist eine OCL-Bedingung, die für einen Diagrammzustand charakterisiert, welche Objektzustände ihm zugeordnet sind. Zustandsinvarianten verschiedener Zustände dürfen im Allgemeinen überlappen.
Abbildung 3.31: Begriffsdefinitionen für Statecharts, Teil 1: Zustände

Stimulus
wird von anderen Objekten oder der Laufzeitumgebung verursacht und führt zur Ausführung einer Transition. Ein Stimulus kann zum Beispiel ein Methodenaufruf, ein Remote Procedure Call, der Empfang einer asynchron versandten Nachricht oder die Mitteilung einer Zeitüberschreitung (Timeout) sein.
Transition
Eine Transition führt von einem Quellzustand in einen Zielzustand und beinhaltet eine Beschreibung des Stimulus sowie der Reaktion in Form einer Aktion. Zusätzliche OCL-Bedingungen erlauben die Schaltbereitschaft und die Reaktion einer Transition weiter zu präzisieren.
Schaltbereitschaft
Eine Transition ist genau dann schaltbereit, wenn sich das Objekt im Quellzustand der Transition befindet, der Stimulus korrekt ist und die Vorbedingung der Transition zutrifft. Sind mehrere Transitionen in derselben Situation schaltbereit, so ist das Statechart nichtdeterministisch und es ist nicht festgelegt, welche Transition ausgewählt wird.
Vorbedingung der Transition
Zusätzlich zum Quellzustand und dem Stimulus ist es möglich, die Schaltbereitschaft einer Transition durch eine OCL-Bedingung einzuschränken, die für die Attributwerte und den Stimulus erfüllt sein muss.
Nachbedingung der Transition (auch: Aktionsbedingung)
Neben einer operationellen Beschreibung der Reaktion auf einen Stimulus kann durch eine OCL-Bedingung eine eigenschaftsorientierte Einschränkung der möglichen Reaktion gegeben werden.
Abbildung 3.32: Begriffsdefinitionen für Statecharts, Teil 2: Transitionen

Aktion
Eine Aktion ist eine durch operationellen Code (also zum Beispiel Java) oder durch eine OCL-Bedingung beschriebene Veränderung des Zustands eines Objekts und seiner Umgebung. Eine Transition enthält üblicherweise eine Aktion.
Entry-Aktion
Ein Zustand kann eine entry-Aktion beinhalten, die ausgeführt wird, wenn der Zustand betreten wird. Sind Aktionen operationell beschrieben, so wird die entry-Aktion nach der Transitionsaktion ausgeführt. Liegt eine eigenschaftsorientierte Beschreibung vor, so gilt die Konjunktion beider Beschreibungen.
Exit-Aktion
Analog zur entry-Aktion kann ein Zustand eine exit-Aktion beinhalten. In einer operationellen Form wird diese vor der Transitionsaktion ausgeführt, in der eigenschaftsorientierten Form gilt ebenfalls die Konjunktion.
Do-Aktivität
Ein Zustand kann eine permanent andauernde Aktivität beinhalten, die do-Aktivität genannt wird. Ihre Implementierung kann über verschiedene Mechanismen zur Erzeugung oder Simulation von Parallelität, wie eigene Threads, Timer, o.ä. vorgenommen werden.
Nichtdeterminismus
Existieren in einer Situation mehrere alternative Transitionen, die schaltbereit sind, so spricht man von Nichtdeterminismus des Statecharts. Das Verhalten des Objekts ist damit unterspezifiziert. Es gibt mehrere methodisch sinnvolle Möglichkeiten, Unterspezifikation im Verlauf eines Softwareentwurfs einzusetzen und aufzulösen.
Abbildung 3.33: Begriffsdefinitionen für Statecharts, Teil 3: Aktionen

Ein Statechart beschreibt das Antwortverhalten eines Objekts, das entsteht, wenn ein Stimulus auf dieses Objekt trifft. Ein Stimulus kann dabei einen Methodenaufruf, eine asynchrone Nachricht oder einen Timeout darstellen. Die Bearbeitung des Stimulus wird atomar durchgeführt. Sie ist also nicht unterbrechbar und nicht parallel zu anderen Transitionen desselben Statecharts.

Während ein Objekt typischerweise einen unendlichen Zustandsraum hat, besteht ein Statechart aus einer endlichen, typischerweise sogar kleinen Menge von Diagrammzuständen. Die Diagrammzustände stellen daher eine Abstraktion des Objektzustandsraums dar. Die Beziehung zwischen Diagramm- und Objektzuständen kann durch Hinzufügen von OCL-Bedingungen präzise definiert werden. Gleiches gilt für die Vorbedingungen und Effekte von Transitionen. Abhängig vom Detaillierungsgrad und der Darstellungsform dieser Bedingungen kann ein Statechart daher als ausführbare Implementierung oder als abstrakte Anforderungsbeschreibung angesehen werden. Statecharts können deshalb von der Anforderungsanalyse bis zur Implementierung eingesetzt werden.

Abbildung 3.34 illustriert, wie die endlich vielen Diagrammzustände und Transitionen eines Statecharts mit einem darunter liegenden unendlichen Transitionssystem in Beziehung gesetzt werden, das das Verhalten des Objekts beschreibt.


Abbildung 3.34: Interpretation eines Diagramms

Die Interpretation eines Diagrammelements durch jeweils eine Menge von Zuständen beziehungsweise Transitionen hat einige Effekte, auf deren detaillierte Untersuchung in Band 1 hingewiesen wird. Hier seien nur zusammenfassend wesentliche Eigenschaften festgestellt:

  • Statecharts basieren auf Mealy-Automaten, die neben der Verarbeitung von Stimuli auch die Ausgabe von Ergebnissen, zum Beispiel in Form von Methodenaufrufen und die Änderung des Objektzustands zulassen.
  • Innerhalb des durch das Statechart beschriebenen Objekts existiert keine Parallelität. Die Statcharts der UML/P haben deshalb keine Parallelzustände („And-States“).
  • Statecharts erlauben grundsätzlich Nichtdeterminismus. Dieser kann zu echtem Nichtdeterminismus der Implementierung führen, aber auch als Unterspezifikation des Modells interpretiert und durch detailliertere Angaben später behoben werden.
  • Spontane (ε-)Transitionen modellieren Beobachtungen, bei der der auslösende Stimulus unsichtbar bleibt (zum Beispiel ein interner Methodenaufruf oder ein Timer). Damit sind spontane Transitionen nur eine besondere Form des Nichtdeterminismus.
  • Ein Statechart kann unvollständig sein, indem es für bestimmte Kombinationen aus Zuständen und Stimuli keine Transitionen zur Verfügung stellt. In diesem Fall ist über die Implementierung nichts ausgesagt, also eine robuste Implementierung möglich. Insbesondere wird nicht gefordert, dass die Implementierung den Stimulus ignoriert.
  • Mit einem geeigneten Stereotyp lässt sich bei Unvollständigkeit ein spezifisches Verhalten, zum Beispiel durch Transition in einen Fehlerzustand festlegen.

Die beiden primären Aufgaben von Statecharts sind die Darstellung von Lebenszyklen von Objekten und des Verhaltens einzelner Methoden.

3.4.2 Darstellung von Statecharts

Abbildung 3.35 zeigt einen einzelnen Zustand, der von der Klasse Auction eingenommen werden kann und neben dem Namen AuctionOpen eine Zustandsinvariante, je eine entry-Aktion und exit-Aktion sowie eine do-Aktivität beinhaltet.


Abbildung 3.35: Ein Zustand der Klasse Auktion mit Invariante und Aktionen

Da ein Diagrammzustand einer Menge von Objektzuständen entspricht, kann die in OCL beschriebene Zustandsinvariante dazu verwendet werden, diese Beziehung herzustellen. Zustandsinvarianten müssen nicht disjunkt sein. Sind sie disjunkt, so spricht man von Datenzuständen, ansonsten von Kontrollzuständen. Der Datenzustand eines Objekts wird durch die Attribute des eigenen und gegebenenfalls abhängiger Objekte bestimmt. Der Kontrollzustand manifestiert sich im laufenden System zusätzlich durch den Programmzähler und den Aufrufkeller. Eine Zustandsinvariante kann nur über den Datenzustand sprechen.

Hierarchie kann bei Zuständen zur Verhinderung einer Zustandsexplosion eingesetzt werden. Ein hierarchisch unterteilter Zustand hat wie jeder andere Zustand einen Namen und kann eine Zustandsinvariante, eine entry- und exit-Aktion und eine do-Aktivität enthalten. Die flache und hierarchische Darstellung von Zuständen im Statechart sind wie in Abbildung 3.36 illustriert äquivalent, wenn die Zustandsinvarianten entsprechend beachtet werden.


Abbildung 3.36: Einführung und Expansion von Hierarchie

Abbildung 3.29 zeigt die Markierung für Start- und Endzustände auf oberster Ebene. Innerhalb eines hierarchisch zergliederten Zustands können ebenfalls Start- und Endzustände markiert werden. Sie haben dann allerdings eine etwas andere Bedeutung (siehe Band 1).

Wenn das Objekt im Quellzustand einer Transition ist und die Schaltbedingung erfüllt, dann kann die Transition durchgeführt werden. Dabei wird eine Aktion ausgeführt und der Zielzustand der Transition eingenommen.

Stimuli

Für Stimuli, die zur Auslösung einer Transition führen, werden fünf verschiedene Kategorien unterschieden:

  • Eine Nachricht wird empfangen,
  • ein Methodenaufruf erfolgt,
  • das Ergebnis eines Return-Statements wird als Antwort auf einen früher abgeschickten Aufruf zurückgegeben,
  • eine Exception wird abgefangen oder
  • die Transition tritt spontan auf.

Für das empfangende Objekt macht es keinen Unterschied, ob ein Methodenaufruf asynchron oder als normaler Methodenaufruf übermittelt wird. Im Statechart wird deshalb auch keine Unterscheidung zwischen diesen beiden Arten von Stimuli getroffen. Es ergeben sich deshalb die in Abbildung 3.37 dargestellten Arten von Stimuli für Transitionen.


Abbildung 3.37: Arten von Stimuli für Transitionen
Schaltregeln

Die Schaltbereitschaft einer Transition lässt sich wie folgt charakterisieren:

  1. Das Objekt muss in einem Objektzustand sein, der zum Quellzustand der Transition korrespondiert.
  2. Entweder ist die Transition spontan und benötigt daher keinen auftretenden Stimulus oder der für die Transition notwendige Stimulus ist aufgetreten.
  3. Die in der Stimulusbeschreibung angegebenen Werte (zum Beispiel Methodenparameter) stimmen mit den tatsächlichen Werten des angekommenen Stimulus überein. Sind in der Stimulusbeschreibung Variablen angegeben, so werden diese mit den tatsächlichen Werten belegt.
  4. Die Vorbedingung, die über den Objektzustand und die Parameter des angekommenen Stimulus evaluiert wird, gilt.

Es kann vorkommen, dass eine Vorbedingung in keiner Situation erfüllt werden kann. In diesem Fall ist die Transition sinnlos, da sie nie durchgeführt wird. Es ist durch Nichtdeterminismus (Unterspezifikation) auch möglich, dass mehrere Transitionen gleichzeitig schaltbereit sind. Deshalb muss eine schaltbereite Transition nicht notwendigerweise auch durchgeführt werden. Nichtdeterminismus im Statechart bedeutet aber nicht notwendigerweise, dass die Implementierung nichtdeterministisch sein muss, denn der Programmierer kann die Unterspezifikation nutzen und selbst die geeignetere Realisierung auswählen. Abbildung 3.38 zeigt zwei erlaubte Situationen überlappender Schaltbereiche.


Abbildung 3.38: Situationen überlappender Schaltbereiche

In beiden Fällen (a) und (b) sind jeweils beide Alternativen möglich. Mit expliziten Prioritäten kann Fall (a) deterministisch aufgelöst werden. Für Nichtdeterminismus auf verschiedenen Hierarchiestufen wird darüber hinaus mit dem Stereotyp prio:inner bzw. prio:outer allgemein festgelegt, ob innere oder äußere Transitionen den Vorzug erhalten.

Im Fall eines unvollständigen Statechart kann ebenfalls durch Einsatz eines Stereotypen das Verhalten präzisiert werden.

  1. Mit completion:ignore wird der Stimulus ignoriert.
  2. Ein Fehlerzustand wird eingenommen, wenn ein solcher Zustand mit error markiert ist. Für das Bearbeiten von Exceptions kann ein weiterer Zustand mit exception markiert werden.
  3. Völlige Unterspezifikation am Statechart wird durch den Stereotyp completion:chaos zugelassen.

Wie in Abschnitt 5.2.6, Band 1 diskutiert, ergeben sich damit Unterschiede in der Interpretation des Lebenszyklus eines Objekts. In den ersten beiden Interpretationen wird der Lebenszyklus als maximal möglich, in der letzten als minimal zugesichert verstanden.

Die Verwendung von completion:chaos ist vor allem in der Spezifikationsphase interessant, wenn durch Verfeinerungen das Verhalten noch detailliert, aber nicht verändert werden soll.

Aktionen

Aktionen beschreiben die Reaktion auf den Empfang eines Stimulus in einem bestimmten Zustand, indem sie dem Zustand als entry- beziehungsweise exit-Aktion oder der Transition als Reaktion hinzugefügt werden. UML/P stellt zwei Arten von Aktionen zur Verfügung. Eine prozedurale Form erlaubt die Nutzung von Zuweisungen und Kontrollstrukturen und eine beschreibende Aktionsform ermöglicht es, den Effekt einer Aktion zu charakterisieren, ohne festzulegen, wie diese Aktion tatsächlich realisiert wird.

Prozedurale Aktionen werden mit Java realisiert, beschreibende Aktionen („Aktionsbedingungen“) mit OCL spezifiziert. Abbildung 3.39 beinhaltet einen Ausschnitt aus einem Statechart für die Klasse Auction, in der eine Transition mit prozeduraler Aktionsbeschreibung und einer Nachbedingung zu sehen ist.


Abbildung 3.39: Transition mit prozeduraler und beschreibender Aktion

Aktionsbedingungen können einerseits als redundantes Addendum zu Aktionsanweisungen formuliert werden, um damit zum Beispiel bei Tests eingesetzt zu werden, und andererseits können Aktionsbedingungen die Anweisungen ergänzen. So kann ein Teil des Verhaltens bereits prozedural festgelegt und ein anderer Teil noch durch eine OCL-Bedingung beschreibend charakterisiert sein.

Die Kombination von entry- und exit-Aktionen aus Zuständen und Transitionsaktionen hängt von der Form der vorgegebenen Transition ab. Abbildung 3.40 zeigt den Transfer prozeduraler Aktionen auf die Transitionen und demonstriert, in welcher Reihenfolge entry- beziehungsweise exit-Aktionen in hierarchischen Zuständen ausgeführt werden. Prozedurale Aktionen werden also sequentiell komponiert.


Abbildung 3.40: Entry- und exit-Aktion in hierarchischen Zuständen

Sind die Aktionen eines Statecharts durch OCL-Aktionsbedingungen spezifiziert, so wird, wie in Abbildung 3.41 gezeigt, statt der sequentiellen Komposition die logische Konjunktion verwendet.


Abbildung 3.41: Bedingungen als entry- und exit-Aktion in Zuständen

Eine Alternative zur logischen Komposition ist in Band 1 erklärt und charakterisiert eine abschnittsweise Gültigkeit der Bedingungen, die zum Beispiel bei Transitionsschleifen notwendig ist.

Weiterführende Konzepte

Zustandsinterne Transitionen sind eigenständige Transitionen, bei denen die entry- oder exit-Aktion des Zustands nicht durchgeführt werden. Abbildung 3.42 zeigt, wie eine zustandsinterne Transition verstanden werden kann.


Abbildung 3.42: Zustandsinterne Transitionen

Wenn ein Zustand eine Situation des Objekts repräsentiert, in der eine Aktivität herrscht, zum Beispiel eine Warnmeldung blinkt, kann sie durch eine do-Aktivität beschrieben werden. Abbildung 3.43 charakterisiert deren Interpretation durch einen Timer.


Abbildung 3.43: do-Aktivität als zeitgesteuerte Wiederholung einer Aktion

Die in den beiden Abbildungen 3.42 und 3.43 eingeführten Konzepte werden durch Transformation auf bereits vorhandene Konzepte der Statecharts erklärt. In Band 1 ist ein aus 19 Regeln bestehendes Transformationssystem angegeben, das Statecharts vollständig auf flache Mealy-Automaten reduziert und so für eine weitere Bearbeitung einfacher zugänglich macht. Damit besitzen Statecharts einen Transformations-Kalkül, der für die semantikerhaltende Verfeinerung geeignet ist.


Bernhard Rumpe. Agile Modellierung mit UML. Springer 2012