Verhalten richtig modellieren

Systeme sind dynamisch. Fahrzeuge bewegen sich, Ampeln wechseln die Farbe. Dynamisches Verhalten richtig zu beschreiben ist eine der Herausforderungen im Systems Engineering. Dies passiert auf vielen Ebenen, bis hin zum kleinsten Implementierungsdetail, sei es in der Form von sich drehenden Zahnrädern oder Softwarefunktionen.

Um Verhalten zu beschreiben, brauchen wir erst einmal ein Vokabular. Klassisch wird dies über ein Glossar verwaltet. In der Modellierung können dafür bspw. SysML-Blöcke benutzt werden, oder UML-Klassen. Blöcke wurden hier kürzlich beschrieben. Der ebenfalls hier beschriebene ICONIX-Prozess benutzt UML-Klassen, um die Domäne zu beschreiben. Dort ist übrigens auch die Unterscheidung zwischen dynamischen und statischen Aspekten schön zu sehen.

Dynamische Anforderungen

Klassische Textschablonen, die schon im ISO-Standard 29148 (Requirements Engineering) und dessen Vorgänger zu finden sind:

Quelle: ISO/IEC/IEEE 29148:2011, Figure 1

Dieser Ansatz funktioniert, skaliert aber nicht sonderlich gut. Die Modellierung ermöglicht es uns, zu skalieren. Zum Beispiel kann über Modellierung die Konsistenz sichergestellt werden.

Anwendungsfälle (Use Cases)

Dynamische Anforderungen werden typischerweise mit Use Cases modelliert, die es sowohl in der UML als auch der SysML gibt. Recht bekannt sind die Diagramme:

Quelle: Modeling Requirements with Constraints, RE-Magzine

Doch viel wichtiger sind eigentlich die Tabellen, die das genaue Verhalten beschreiben:

UC-NameLogging out
ActorsAny logged in user
DescriptionAs a user, I want to log out of the system, so that nobody can access my account from this browser session.
PreconditionsUser is logged into the system
Activity[User] initiates log out

[System] logs the user out of the system and displays a corresponding message
PostconditionsUser is logged out of the system

Dieses Beispiel stammt aus einem Artikel, den ich im RE-Magazine des IREB veröffentlicht habe.

Anwendungsfälle werden typischerweise für Nutzeranforderungen benutzt, sie lassen sich aber auch für Systemanforderungen einsetzen. Die Aktoren müssen keine Menschen sein, es kann sich auch um andere Systeme handeln.

Aktivitäten

Die Aktivitäten eines Anwendungsfalles können über Aktivitätsdiagramme ausdetailliert werden. Bei einem linearen Ablauf ist das Overkill, ist jedoch sehr nützlich, wenn es Verzweigungen oder Schleifen im Ablauf gibt. Da eine Aktivität selbst ein Modellelement ist, kann diese Informationen enthalten, die in einer einfachen (informellen) Aktivitätsliste nicht zu finden sind. Auch hier können wir also je nach Bedarf den Grad der Formalisierung erhöhen, was uns wiederum einen Nutzen bringen kann.

https://upload.wikimedia.org/wikipedia/commons/thumb/c/c2/Uml-Activity-Beispiel1.svg/500px-Uml-Activity-Beispiel1.svg.png
Quelle: Wikipedia

Zustände

Es gibt auch das Zustandsdiagramm, und das ist manchmal für Einsteiger verwirrend, da es dem Aktivitätsdiagramm ähnelt.

https://upload.wikimedia.org/wikipedia/commons/thumb/f/fa/Uml-Zustandsdiagramm-3.svg/922px-Uml-Zustandsdiagramm-3.svg.png
Quelle: Wikipedia

Der Unterschied zwischen Aktivitäten und Zuständen ist jedoch sehr wichtig. Konkretes Beispiel:

  • Die Aktivität „Erhöhe die Variable um eins“ führt zu immer neuen Zuständen der Variable. Aus 1 wird 2, aus 2 wird 3, usw.
  • Der Zustand „Ampel ist gelb“ kann auf zwei Wegen erreicht werden: „Von grün nach gelb“ und „Von rot nach gelb“.

Sequenzen

Bei Sequenzdiagrammen geht es um den Austausch von Nachrichten zwischen Objekten. Diese ähneln Aktivitätsdiagrammen, sind jedoch oft eine Ebene tiefer zu finden, also Lösungsnäher.

https://upload.wikimedia.org/wikipedia/commons/thumb/5/50/UmlSequenzdiagramm-2.svg/500px-UmlSequenzdiagramm-2.svg.png
Quelle: Wikipedia

Funktionen und Methoden

Auf der Implementierungsebene, in Softwarecode, gibt es selbstverständlich auch dynamisches Verhalten. Dieses ist je nach Programmiersprache in Funktionen oder Methoden zu finden.

Spannend hierbei ist, dass es der enthaltene Code die Umsetzung beschreibt. Doch wo ist die Spezifikation? Dazu gibt es verschiedene Techniken, wie bspw. Programming by Contract, welches sorgfältig Pre- und Postconditions definiert und auch auswerten kann. Ein anderer Ansatz ist der Einsatz von Unit Tests. Diese können auch mit einer Testfallgenerierung aus dem Modell kombiniert werden.

Fazit

Es gibt einen Reihe von Modellierungstechniken für dynamisches Verhalten, und diese können auf vielen Ebenen ansetzen. Denn dynamisches Verhalten zieht sich durch das gesamte System.

In der Praxis ist weniger mehr: Im Zweifelsfall lieber ein Modelltyp weniger als einer mehr. Im Zweifelsfall lieber etwas informeller aus zu formal und zu tief.

Trotzdem: Am Ende des Tages ist es das Verhalten des Systems, was einen Nutzen bringt. Dieses richtig festzuhalten und umzusetzen ist eine wichtige Aufgabe in der Systementwicklung.

Titelbild: Pixabay

jastram

Creator and Author of SE-Trends