Richtlinie: Zustandsdiagramm
Zustandsdiagramme sind eine formale grafische Darstellung für die Spezifikation von Zustandsmaschinen, die für die Modellierung des dynamischen Verhaltens von Modellelementen verwendet werden. Diese Richtlinie beschreibt diese Darstellungsform und veranschaulicht, wie sie effektiv verwendet wird.
Beziehungen
Hauptbeschreibung

Erläuterung

Zustandsmaschinen werden verwendet, um das dynamische Verhalten eines Modellelements und noch spezifischer die ereignisgesteuerten Aspekte des Systemverhaltens zu modellieren (siehe Konzept: Ereignisse und Signale). Zustandsmaschinen werden insbesondere verwendet, um zustandsabhängiges Verhalten oder Verhalten zu definieren, das je nach Zustand des Modellelements variiert, zu definieren. Modellelemente, dessen Verhalten nicht mit dem Zustand des Elements variiert, erfordern keine Zustandsmaschine für die Beschreibung ihres Verhaltens. Diese Elemente sind in der Regel passive Klassen, die primär für die Verwaltung von Daten zuständig sind. Zustandsmaschinen müssen verwendet werden, um das Verhalten aktiver Klassen zu modellieren, die Aufrufereignisse und Signalereignisse verwenden, um ihre Operationen zu implementieren (als Übergänge in der Zustandsmaschine der Klasse).

Eine Zustandsmaschine setzt sich aus Zuständen zusammen, die durch Übergänge verbunden sind. Ein Zustand ist eine Bedingung eines Objekts, in dem er eine Aufgabe ausführt oder auf ein Ereignis wartet. Ein Übergang ist eine Beziehung zwischen zwei Zuständen, der durch ein Ereignis ausgelöst wird, der bestimmte Aktionen oder Auswertungen ausführt und der zu einem bestimmten Endzustand führt. Die Elemente einer Zustandsmaschine sind in Abbildung 1 dargestellt.

Abbildung mit der Darstellung einer Zustandsmaschine

Abbildung 1. Darstellung einer Zustandsmaschine

Sie können sich einen einfachen Editor als finite Zustandsmaschine mit den Zuständen Leer, Warten auf Befehl und Warten auf Text vorstellen. Die Ereignisse Datei laden, Text einfügen, Zeichen einfügen und Speichern und verlassen bewirken Übergänge in der Zustandsmaschine. Die Zustandsmaschine für den Editor ist in Abbildung 1 dargestellt.

In der Überschrift genannte Abbildung

Abbildung 2. Die Zustandsmaschine für einen einfachen Editor

Zustände

Ein Zustand ist eine Bedingung eines Objekts, in dem er eine Aufgabe ausführt oder auf ein Ereignis wartet. Ein Objekt kann für eine begrenzte Zeit in einem Zustand verbleiben. Ein Zustand hat mehrere Eigenschaften:

Name Eine Zeichenfolge, anhand der dieser Zustand von anderen Zuständen unterschieden wird. Ein Zustand kann auch anonym sein, d. h. er hat keinen Namen.
Eintritts-/Austrittsaktionen Aktionen, die beim Eintritt in einen und Austritt aus einem Zustand ausgeführt werden.
Interne Übergänge Übergänge, die keine Zustandsänderung bewirken.
Unterzustände Die verschachtelte Struktur eines Zustands mit disjunkten (sequenziell aktiven) oder parallelen (gleichzeitig aktiven) Unterzuständen.
Verzögerte Ereignisse Eine Liste mit Ereignissen, die in diesem Zustand nicht bearbeitet werden, aber für die Bearbeitung durch ein Objekt in einem anderen Zustand zurückgestellt und in eine Warteschlange gestellt werden.

Wie in Abbildung 1 gezeigt, können für die Zustandsmaschine eines Objekts zwei Sonderzustände definiert werden. Der Anfangszustand gibt den Ausgangspunkt für die Zustandsmaschine bzw. den Unterzustand an. Ein Anfangszustand wird als gefüllter schwarzer Kreis dargestellt. Der Endzustand zeigt den Abschluss der Ausführung der Zustandsmaschine oder den Abschluss des übergeordneten Zustands an. Ein Endzustand wird als gefüllter schwarzer Kreis in einem nicht gefüllten Kreis angezeigt. Anfangs- und Endzustände sind in Wirklichkeit Pseudozustände. Beide können mit Ausnahme eines Namens dieselben Eigenschaften wie ein normaler Zustand haben. Ein Übergang von einem Anfangszustand in einen Endzustand kann das vollständige Komplement von Features einschließlich einer Wächterbedingung und einer Aktion, aber kein Auslöseereignis haben.

Übergänge

Ein Übergang ist eine Beziehung zwischen zwei Zuständen, die anzeigt, dass ein Objekt im ersten Zustand bestimmte Aktionen ausführt und dann in einen zweiten Zustand wechselt, wenn ein bestimmtes Ereignis eintritt und bestimmte Bedingungen erfüllt sind. Bei einer solchen Zustandsänderung wird der Übergang "ausgelöst". Bis der Übergang ausgelöst wird, ist das Objekt im "Quellenzustand". Nachdem der Übergang ausgelöst wurde, ist das Objekt im "Zielzustand". Ein Übergang hat mehrere Eigenschaften:

Quellenzustand Der durch den Übergang betroffene Zustand. Wenn ein Objekt im Quellenzustand ist, kann ein Ausgangsübergang ausgelöst werden, wenn das Objekt das Auslöserereignis empfängt und die Wächterbedingung, sofern vorhanden, erfüllt ist.
Ereignisauslöser Das Ereignis, das den Übergang auslöst (vorausgesetzt, dass die Wächterbedingung erfüllt ist), wenn es vom Objekt im Quellenzustand empfangen wird.
Wächterbedingung Ein Boolescher Ausdruck, der ausgewertet wird, wenn der Übergang durch den Empfang des Ereignisauslösers ausgelöst wird. Wenn die Auswertung des Booleschen Ausdrucks true ergibt, wird der Übergang ausgelöst. Ist das Ergebnis der Auswertung false, wird der Übergang nicht ausgelöst. Falls kein anderer Übergang vorhanden ist, der durch dasselbe Ergebnis ausgelöst werden könnte, geht das Ereignis verloren.
Aktion Eine ausführbare atomare Berechnung, die direkt mit das Objekt, das Eigner der Zustandsmaschine ist, oder indirekt andere Objekten bearbeiten kann, die für das Objekt sichtbar sind.
Zielzustand Der Zustand, der nach Abschluss des Übergangs aktiv ist.

Ein Übergang kann mehrere Quellen haben. In diesem Fall stellt der Übergang eine Verknüpfung mehrerer paralleler Zustände sowie mehrerer Ziele und damit eine Verzweigung zu mehreren parallelen Zuständen dar.

Ereignisauslöser

Im Kontext einer Zustandsmaschine ist ein Ereignis das Vorkommen eines Stimulus, das einen Zustandsübergang auslösen kann. Ereignisse können Signalereignisse, Aufrufereignisse, das Vergehen von Zeit oder eine Änderung eines Zustands sein. Ein Signal oder ein Aufruf kann Parameter haben, deren Werte für den Übergang verfügbar sind, einschließlich Ausdrücken für die Wächterbedingungen und die Aktion. Auslöserlose Übergänge sind ebenfalls möglich. Diese werden durch einen Übergang ohne Ereignisauslöser dargestellt. Diese Übergänge, auch Abschlussübergänge genannt, werden implizit ausgelöst, wenn der zugehörige Quellenzustand seine Aufgabe ausgeführt hat.

Wächterbedingungen

Eine Wächterbedingung wird ausgewertet, nachdem das Auslöseereignis für den Übergang eingetreten ist. Es kann mehrere Übergänge aus demselben Quellenzustand mit demselben Ereignisauslöser geben, solange die Wächterbindungen nicht überlappen. Eine Wächterbedingung wird nur einmal und zwar, wenn das Ereignis eintritt, für den Übergang ausgewertet. Der Boolesche Ausdruck kann auf den Zustand des Objekts verweisen.

Aktionen

Eine Aktion ist eine ausführbare atomare Berechnung, d. h. sie kann nicht durch ein Ereignis unterbrochen werden und wird deshalb bis zur Fertigstellung ausgeführt. Eine Aufgabe hingegen kann von anderen Ereignissen unterbrochen werden. Aktionen können Operationsaufrufe (an den Eigner der Zustandsmaschine sowie andere sichtbare Objekte), das Erstellen und Löschen eines anderen Objekts oder das Senden eines Signals an ein anderes Objekt beinhalten. Wenn ein Signal gesendet wird, wird dem Signalnamen das Schlüsselwort 'send' vorangestellt.

Eintritts- und Austrittsaktionen

Eintritts- und Austrittsaktionen ermöglichen, dass dieselbe Aktion bei jedem Eintritt bzw. Austritt in den Zustand verteilt werden kann. Durch die Eintritts- und Austrittsaktionen erfolgt dieser Vorgang sauber, ohne die Aktionen explizit in jeden Eingangs- oder Ausgangsübergang stellen zu müssen. Eintritts- und Austrittsaktionen können keine Argumente und Wächterbedingungen haben. Die Eintrittsaktionen auf der Ausgangsebene einer Zustandsmaschine für ein Modellelement können Parameter haben, die die Argumente darstellen, die die Maschine empfängt, wenn das Element erstellt wird.

Interne Übergänge

Mit internen Übergängen können Ereignisse in der Zustandsmaschine bearbeitet werden, ohne den Zustand zu verlassen. Auf diese Weise wird das Auslösen von Eintritts- oder Austrittsaktionen verhindert. Interne Übergänge können Ereignisse mit Parametern und Wächterbedingungen haben und stellen im Wesentlichen Interrupt-Handler dar.

Verzögerte Ereignisse

Verzögerte Ereignisse sind Ereignisse, deren Bearbeitung so lange zurückgestellt wird, bis ein Zustand aktiv wird, in dem das Ereignis nicht mehr zurückgestellt wird. Wenn dieser Zustand aktiv wird, wird das Ereignis ausgelöst und kann Übergänge so auslösen, als wäre es gerade erst eingetreten. Die Implementierung von verzögerten Ereignissen setzt das Vorhandensein einer internen Warteschlange von Ereignissen voraus. Wenn ein Ereignis eintritt, aber als verzögertes Ereignis aufgelistet ist, wird es in die Warteschlange gestellt. Ereignisse werden aus dieser Warteschlange genommen, sobald das Objekt einen Zustand erreicht, in dem diese Ereignisse nicht mehr zurückgestellt werden.

Unterzustände

Ein einfacher Zustand ist ein Zustand, der keine Unterstruktur hat. Ein Zustand, der Unterzustände (verschachtelte Zustände) hat, ist ein zusammengesetzter Zustand. Unterzustände können bis zu einer beliebigen Ebene verschachtelt werden. Eine verschachtelte Zustandsmaschine kann maximal einen Anfangszustand und einen Endzustand haben. Unterzustände werden verwendet, um komplexe, flache Zustandsmaschinen zu vereinfachen, und zeigen, dass gewisse Zustände nur in einem bestimmten Kontext möglich sind (übergeordneter Zustand).

Abbildung mit einer Darstellung von Unterzuständen

Abbildung 3. Unterzustände

Von einer Quelle außerhalb eines übergeordneten zusammengesetzten Zustands kann ein Übergang den zusammengesetzten Zustand oder einen Unterzustand als Ziel haben. Wenn das Ziel der zusammengesetzte Zustand ist, muss die verschachtelte Zustandsmaschine einen Anfangszustand haben, an den die Steuerung nach dem Eintritt in den zusammengesetzten Zustand und nach der Verteilung der Eintrittsaktion (sofern vorhanden) übergeben wird. Wenn das Ziel der verschachtelte Zustand ist, wird die Steuerung an den verschachtelten Zustand übergeben, nachdem die Eintrittsaktion des zusammengesetzten Zustands (sofern vorhanden) und anschließend die Eintrittsaktion des verschachtelten Zustands (sofern vorhanden) verteilt wurde.

Ein Übergang, der von einem zusammengesetzten Zustand ausgeht, kann als Quelle den zusammengesetzten Zustand oder einen Unterzustand haben. In beiden Fällen verlässt die Steuerung zuerst den verschachtelten Zustand (und die zugehörige Austrittsaktion, sofern vorhanden, wird verteilt) und anschließend den zusammengesetzten Zustand (und die zugehörige Austrittsaktion, sofern vorhanden, wird verteilt). Ein Übergang, dessen Quelle der zusammengesetzte Zustand ist, unterbricht die Aufgabe der verschachtelten Zustandsmaschine.

Historienzustände

Sofern nicht anders angegeben, beginnt beim Eintritt eines Übergangs in einen zusammengesetzten Zustand die Aktion der verschachtelten Zustandsmaschine wieder beim Anfangszustand (sofern das direkte Ziel des Übergangs kein Unterzustand ist). Historienzustände erlauben der Zustandsmaschine, erneut in den letzten aktiven Unterzustand vor dem Verlassen des zusammengesetzten Zustands zu wechseln. Ein Beispiel für einen Historienzustand ist in Abbildung 3 dargestellt.

Abbildung mit einer Darstellung von Historienzuständen

Abbildung 4. Historienzustand

Gängige Modellierungstechniken

Zustandsmaschinen sind ein gängiges Mittel, um das Verhalten eines Objekts in seinem Lebenszyklus zu modellieren. Sie werden insbesondere dann benötigt, wenn Objekt zustandsabhängiges Verhalten aufweisen. Zu den Objekten, die Zustandsmaschinen haben können, gehören Klassen, Subsysteme, Anwendungsfälle und Schnittstellen (um Zustände zuzusichern, die von einem Objekt erfüllt werden müssen, das die Schnittstelle realisiert). Bei Echtzeitsystemen werden Zustandsmaschinen auch für Kapseln und Protokolle verwendet (um Zustände zuzusichern, die von einem Objekt erfüllt werden müssen, das das Protokoll realisiert).

Nicht alle Objekte erfordern Zustandsmaschinen. Wenn das Verhalten eines Objekts einfach ist, z. B. dass das Objekt einfach Daten speichert oder abruft, ist das Verhalten des Objekts zustandsunabhängig und seine Zustandsmaschine relativ uninteressant.

Zur Modellierung der Lebensdauer eines Objekts gehören drei Dinge: die Ereignisse angeben, auf die ein Objekt antworten kann, die Antwort auf diese Ereignisse und die Auswirkung des Geschehenen auf das aktuelle Verhalten. Außerdem muss bei der Modellierung der Lebensdauer eines Objekts die Reihenfolge festgelegt werden, in der das Objekt sinnvoll auf Ereignisse reagieren kann, angefangen vom Zeitpunkt, zu dem das Objekt erstellt wird, bis hin zu dem Zeitpunkt, zu dem das Objekt gelöscht wird.

Gehen Sie zum Modellieren der Lebensdauer eines Objekts wie folgt vor:

  • Legen Sie den Kontext für die Zustandsmaschine fest, egal ob es sich um eine Klasse, einen Anwendungsfall oder das System als Ganzen handelt.
    • Wenn der Kontext eine Klasse oder ein Anwendungsfall ist, stellen Sie die Nachbarklassen, einschließlich der übergeordneten Klassen und der Klassen zusammen, die durch Assoziationen oder Abhängigkeiten erreichbar sind. Diese Nachbarklassen sind potenzielle Ziele für Aktionen und für den Einschluss in Wächterbedingungen.
    • Wenn der Kontext das System als Ganzes ist, grenzen Sie den Schwerpunkt auf ein Verhalten des Systems ein und machen Sie sich dann Gedanken über die Lebensdauer der Objekte, die zu diesem Aspekt gehören. Die Lebensdauer des gesamten Systems ist einfach zu groß, um einen sinnvollen Schwerpunkt zu bilden.
  • Legen Sie den Anfangs- und den Endzustand für das Objekt fest. Wenn es Vorbedingungen oder Nachbedingungen für den Anfangs- und den Endzustand gibt, definieren Sie auch diese.
  • Bestimmen Sie die Ereignisse, auf die das Objekt reagiert. Sie finden diese Ereignisse in den Schnittstellen des Objekts. Bei Echtzeitsystemen sind diese auch in den Protokollen des Objekts zu finden.
  • Ordnen Sie die übergeordneten Zustände, angefangen beim Anfangszustand bis hin zum Endzustand, fest, die das Objekt annehmen kann. Verbinden Sie diese Zustände durch Übergänge, die durch die entsprechenden Ereignisse ausgelöst werden. Fahren Sie fort, indem Sie diese Übergänge hinzufügen.
  • Identifizieren Sie jede Eintritts- und jedes Austrittsaktion.
  • Erweitern oder vereinfachen Sie die Zustandsmaschine mit Unterzuständen.
  • Stellen Sie sicher, dass alle Ereignisse, die Übergänge in der Zustandsmaschine auslösen, Ereignissen entsprechen, die von den vom Objekt realisierten Schnittstellen erwartet werden. Prüfen Sie außerdem, ob alle Ereignisse, die von den Schnittstellen des Objekts erwartet werden, in der Zustandsmaschine berücksichtigt werden. Bei Echtzeitsystemen müssen Sie entsprechende Prüfungen für die Protokolle einer Kapsel vornehmen. Suchen Sie schließlich nach Stellen, an denen Sie Ereignisse explizit ignorieren möchten (z. B. verzögerte Ereignisse).
  • Stellen Sie sicher, dass alle Aktionen in der Zustandsmaschine durch Beziehungen, Methoden und Operationen des übergeordneten Objekts unterstützt werden.
  • Verfolgen Sie die Zustandsmaschine und vergleichen Sie sie mit den erwarteten Abfolgen von Ereignissen und Antworten. Suchen Sie nach unerreichbaren Zuständen und Zuständen, in denen die Maschine blockiert.
  • Wenn Sie die Zustandsmaschine neu anordnen oder umstrukturieren, müssen Sie sicherstellen, dass die Semantik nicht geändert wurde.

Hinweise und Tipps

  • Wenn Sie die Möglichkeit haben, verwenden Sie die visuelle Semantik der Zustandsmaschine, anstatt detaillierten Übergangscode zu schreiben. Lösen Sie beispielsweise nicht einen Übergang bei mehreren Signalen aus und verwenden dann Detailcode, um den Steuerungsablauf je nach Signal anders zu verwalten. Verwenden Sie getrennte Übergänge, die von getrennten Signalen ausgelöst werden. Vermeiden Sie bedingte Logik in Übergangscode, der zusätzliches Verhalten verbirgt.
  • Benennen Sie Zustände danach, auf was Sie warten oder was während des Zustands passiert. Denken Sie daran, dass ein Zustand kein 'Zeitpunkt' ist, sondern ein Zeitraum, in dem die Zustandsmaschine auf etwas wartet. Beispiel eignet sich der Name 'WartenAufEnde' besser als 'Ende' und 'ZeitplanungEinerAufgabe' besser als 'Zeitlimit'. Benennen Sie Zustände nicht so, als wären sie Aktionen.
  • Benennen Sie alle Zustände und Übergänge in einer Zustandsmaschine einheitlich. Damit wird das Debugging auf Quellenebene einfacher.
  • Verwenden Sie Zustandsvariablen (Attribut zum Steuern des Verhaltens) mit Vorsicht. Verwenden Sie sie nicht, um sich das Erstellen neuer Zustände zu sparen. Zustandsvariablen können verwendet werden, wenn es nur wenige Zustände mit wenig oder keinem zustandsabhängigen Verhalten oder wenig oder gar kein Verhalten gibt, das parallel zum oder unabhängig vom Objekt erbracht wird. Wenn es sich um komplexes, zustandsabhängiges Verhalten mit potenziell parallelem Charakter handelt oder wenn Ereignisse, die verarbeitet werden müssen, nicht aus dem Objekt mit der Zustandsmaschine stammen, können Sie eine Kollaboration von zwei oder mehr aktiven Objekten (möglicherweise definiert als Komposition) verwenden. In Echtzeitsystemen sollte komplexes, zustandsabhängiges, paralleles Verhalten mit einer Kapsel modelliert werden, die unterordnete Kapseln enthält.
  • Wenn es mehr als 5 ± 2 Zustände in einem Diagramm gibt, können Sie Unterzustände verwenden. Zehn Zustände in einem vollkommen regulären Muster können in Ordnung sein, aber zwei Zustände mit 40 Übergängen zwischen ihnen müssen offensichtlich neu überdacht werden. Stellen Sie sicher, dass die Zustandsmaschine verständlich ist.
  • Benennen Sie Übergänge danach, was das Ereignis auslöst und/oder was während des Übergangs passiert. Wählen Sie Namen, die der Verständlichkeit zuträglich sind.
  • Wenn Sie einen Auswahlscheitelpunkt sehen, müssen Sie sich fragen, ob Sie die Zuständigkeit für diese Auswahl an eine andere Komponente delegieren können, so dass sie dem Objekt als eindeutige Signalgruppe präsentiert werden kann (z. B. anstelle einer Auswahl von Nachricht-> Daten> x), oder ob Sie dem Sender oder einem anderen zwischengeschalteten Akteur die Entscheidung überlassen sollen, der dann ein Signal mit der Entscheidung explizit im Signalnamen senden soll (verwenden Sie z. B. Signale mit den Namen istVoll und istLeer anstelle von Signalen mit den Namen Wert und Nachrichtendatenprüfen).
  • Benennen Sie die beim Auswahlscheitelpunkt zu beantwortete Frage beschreibend, z. B. 'istImmerNochWasLos' oder 'istEsZeitSichZuBeschweren'.
  • Versuchen Sie, die Namen von Auswahlscheitelpunkten in einem Objekt eindeutig zu halten (aus demselben Grund wie bei den Namen von Übergängen).
  • Enthalten Übergänge überlange Codefragmente? Sollten stattdessen Funktionen verwendet werden, und werden allgemeine Codefragmente als Funktionen erfasst? Ein Übergang sollte sich wie Pseudocode auf hoher Ebene lesen lassen und sich an dieselben oder sogar strengere Regeln halten als C++-Funktionen. Ein Übergang mit mehr als 25 Zeilen ist übermäßig lang.
  • Funktionen sollten danach benannt werden, was sie tun.
  • Schenken Sie Eintritts- und Austrittsaktionen besondere Aufmerksamkeit. Es passiert relativ leicht, Änderungen vorzunehmen und dann zu vergessen, die Eintritts- und Austrittsaktionen zu ändern.
  • Austrittsaktionen können als Sicherheits-Features verwendet werden (beispielsweise schaltet die Austrittsaktion aus dem Zustand 'HeizungAn' die Heizung aus). Die Aktionen dienen hier als Zusicherung.
  • Im Allgemeinen sollten Unterzustände mindestens zwei Zustände enthalten, sofern die Zustandsmaschine nicht abstrakt ist und von Unterklassen des übergeordneten Elements präzisiert wird.
  • Auswahlpunkte können anstelle von bedingter Logik in Aktionen und Übergängen verwendet werden. Auswahlpunkte sind leicht erkennbar, wohingegen bedingte Logik im Code in der Sicht verdeckt und leicht zu übersehen ist.
  • Vermeiden Sie Wächterbedingungen.
    • Wenn das Ereignis mehrere Übergänge auslöst, kann nicht gesteuert werden, welche Wächterbedingung zuerst ausgewertet wird. Deshalb sind die Ergebnisse nicht vorhersehbar.
    • Es könnten mehrere Wächterbedingungen wahr sein, aber es kann nur einem Übergang gefolgt werden. Der ausgewählte Pfad ist möglicherweise nicht unvorhersehbar.
    • Wächterbedingungen sind nicht visuell und damit schwerer zu erkennen.
  • Vermeiden Sie Zustandsmaschinen, die Ablaufdiagrammen gleichen.
    • Dies kann auf einen Versuch hinweisen, eine Abstraktion zu modellieren, die eigentlich nicht vorhanden ist, z. B.:
      • Verwendung einer aktiven Klasse zur Modellierung von Verhalten, das sich am besten für eine passive oder eine Datenklasse eignet.
      • Modellierung einer Datenklasse unter Verwendung einer Datenklasse und einer aktiven Klasse, die eng miteinander gekoppelt sind (d. h. die Datenklasse wird für die Übergabe von Typinformationen verwendet, aber die aktive Klasse enthält die meisten Daten, die der Datenklasse zugeordnet werden müssen).
    • Dieser unsachgemäße Gebrauch von Zustandsmaschinen lässt sich an den folgenden Symptomen erkennen:
      • Nachrichten, die primär "an sich selbst" gesendet werden, um einfach Code wiederzuverwenden.
      • Wenige Zustände mit vielen Auswahlpunkten.
      • In einigen Fällen eine Zustandsmaschine ohne Zyklen. Solche Zustandsmaschinen sind gültig in Prozesssteuerungsanwendungen oder zur Steuerung einer Ereignisfolge. Ihr Vorhandensein während der Analyse stellt gewöhnlich die Degeneration der Zustandsmaschine in ein Ablaufdiagramm dar.
    • Wenn Sie das Problem identifiziert haben, können Sie wie folgt vorgehen:
      • Die aktive Klasse in kleinere Einheiten mit eindeutigeren Zuständigkeiten unterteilen.
      • Mehr Verhalten in eine Datenklasse verschieben, die der fraglichen aktiven Klasse zugeordnet ist.
      • Mehr Verhalten in die Funktionen der aktiven Klasse verschieben.
      • Aussagefähigere Signal erstellen, anstatt sich auf Daten zu verlassen.

Design mit abstrakten Zustandsmaschinen

Eine abstrakte Zustandsmaschine ist eine Zustandsmaschine, der weitere Details zugeordnet werden müssen, damit sie für praktische Zwecke eingesetzt werden kann. Abstrakte Zustandsmaschinen können verwendet werden, um generisches, wiederverwendbare Verhalten zu definieren, das in nachfolgenden Modellelementen weiter präzisiert wird.

In der Überschrift genannte Abbildung

Abbildung 5. Eine abstrakte Zustandsmaschine

Schauen Sie sich die abstrakte Zustandsmaschine in Abbildung 5 an. Die dargestellte Beispielzustandsmaschine repräsentiert die abstrakteste Verhaltensebene (den Steuerautomaten) vieler unterschiedlicher Typen von Elementen in ereignisgesteuerten Systemen. Obwohl alle Elemente dieses Verhalten der oberen Ebene aufweisen, können die unterschiedlichen Elementtypen je nach ihrem Zweck stark unterschiedliches Detailverhalten im Zustand "Aktiv" haben. Deshalb liegt es nahe, diese Zustandsmaschine in einer abstrakten Klasse zu definieren, die als Stammklasse für die unterschiedlichen, spezialisierten aktiven Klassen dient.

Lassen Sie uns deshalb zwei solche Präzisierungen dieser abstrakten Zustandsmaschine durch Vererbung definieren. Diese beiden Präzisierungen R1 und R2 sehen Sie in Abbildung 6. Zur Verdeutlichung werden die von der übergeordneten Klasse geerbten Elemente mit einem grauen Stift gezeichnet.

In der Überschrift genannte Abbildung

Abbildung 6. Zwei Präzisierungen der Zustandsmaschine in Abbildung 5.

Die beiden Präzisierungen unterscheiden sich klar darin, wie sie den Zustand "Aktiv" zerlegen und wie sie den ursprünglichen Übergang "Start" erweitern. Diese Auswahl kann natürlich erst getroffen werden, nachdem die Präzisierung bekannt ist, und hätte nicht mit einem einzelnen End-to-End-Übergang in der abstrakten Klasse vorgenommen werden können.

Durchgangszustände

Die Fähigkeit, Eingangs- und Ausgangsübergänge "fortzuführen" ist für den zuvor beschriebenen Typ von Präzisierung grundlegend. Eintrittspunkte und Endzustände kombiniert mit fortgeführten Übergängen scheinen für die Unterstützung dieser Semantik ausreichend zu sein. Dies ist jedoch leider nicht der fall, wenn mehrere unterschiedliche Übergänge erweitert werden müssen.

Für das abstrakte Verhaltensmuster ist eine Methode erforderlich, mit der zwei oder mehr Übergangssegmente verkettet werden können, die alle im Rahmen eines vollständigen Schritts ausgeführt werden. Das bedeutet, dass Übergänge in einen hierarchischen Zustand in den Eingangsteil, der an der Zustandsgrenze endet, und eine Erweiterung, die innerhalb des Zustands fortgesetzt wird, aufgeteilt werden. Ausgangsübergänge aus einem hierarchisch verschachtelten Zustand werden in einen Teil, der an der Grenze des übergeordneten Zustands endet, und einen Teil, der von der Zustandsgrenze in den Zielzustand fortgeführt wird, unterteilt. Dieser Effekt kann in UML mit dem neuen Konzept des Durchgangszustands erreicht werden. Dieses Konzept wird mit einem Stereotyp (<<Durchgangszustand>> (Chain State)) des Konzepts des UML-Zustands modelliert. Es handelt sich hierbei um einen Zustand, dessen einziger Zweck die "Verkettung" weiterer automatischer (ohne Auslöser) Übergänge zu einem Eingangsübergang ist. Ein Durchgangszustand hat keine interne Struktur, keine Eintrittsaktion, keine interne Aufgabe und keine Austrittsaktion. Außerdem hat keine Übergänge, die von Ereignissen ausgelöst werden. Er kann jedoch eine Reihe von Eingangsübergängen haben. Er kann einen Ausgangsübergang ohne Auslöserereignis haben. Dieser Übergang wird automatisch ausgelöst, wenn ein Eingangsübergang den Zustand aktiviert. Der Durchgangszustand verkettet einen Eingangsübergang mit einem separaten Ausgangsübergang. Zwischen den Eingangsübergängen und dem verketteten Ausgangsübergang wird ein Zustand mit einem anderen Zustand innerhalb des übergeordneten Zustands und der andere Zustand mit einem anderen Zustand außerhalb des übergeordneten Zustands verbunden. Durch den Durchgangszustand wird eine Trennung der internen Spezifikation des übergeordneten Zustands von seiner externen Umgebung erreicht. Es handelt sich hierbei um eine Art der Kapselung.

Ein Durchgangszustand (oder Pass-Through-Zustand) verkettet einen Übergang mit einem bestimmten fortgeführten Übergang. Wenn kein fortgeführter Übergang definiert ist, endet der Übergang im Durchgangszustand. In diesem Fall muss ein Übergang in einem übergeordneten Zustand ausgelöst werden, damit es weitergehen kann.

Das Segment mit der Beispielzustandsmaschine in Abbildung 7 veranschaulicht Durchgangszustände und ihre Darstellung. Durchgangszustände werden in einem Zustandsmaschinendiagramm durch kleine weiße Kreise im entsprechenden hierarchischen Zustand dargestellt (diese Darstellung gleicht der von Anfangs- und Endzuständen, denen die Durchgangszustände ähneln). Die Kreise sind Stereotypsymbole für den Stereotyp "Durchgangszustand" (Chain State) und werden normalerweise nahe der Grenze gezeichnet. (Eine Darstellungsvariante ist, diese Symbole direkt auf der Grenze zum übergeordneten Zustand zu zeichnen.)

Im Begleittext beschriebene Abbildung

Abbildung 7. Durchgangszustände und verkettete Übergänge

Der verkettete Übergang in diesem Beispiel setzt sich aus den drei verketteten Übergangssegmenten e1/a11-/a12-/a13 zusammen. Wenn Signal e1 empfangen wird, wird der Übergang e1/a11 gewählt, seine Aktion a11 wird ausgeführt, und schließlich wird der Übergangszustand c1 erreicht. Danach wird der fortgeführte Übergang zwischen c1 und c2 gewählt, und da c2 auch ein Übergangszustand ist, danach der Übergang von c2 nach S21. Wenn die Zustände entlang dieser Pfade Austritts- und Eintrittsaktionen haben, werden die Aktionen wie folgt nacheinander ausgeführt:

  • Austrittsaktion von S11
  • Aktion a11
  • Austrittsaktion von S1
  • Aktion a12
  • Eintrittsaktion von S2
  • Aktion a13
  • Eintrittsaktion von S21

Alle Aktionen werden im Rahmen eines einzelnen vollständigen Schritts ausgeführt.

Vergleichen Sie dies mit der Aktionsausführungssemantik des direkten Übergangs e2/a2:

  • Austrittsaktion von S11
  • Austrittsaktion von S1
  • Aktion a2
  • Eintrittsaktion für Zustand S2
  • Eintrittsaktion für Zustand S21