# Aktivität (UML)

Eine Aktivität (engl. Activity) ist ein Modellelement in der Unified Modeling Language (UML), einer Modellierungssprache für Software und andere Systeme. Sie modelliert das Verhalten eines Systems, indem sie beschreibt, wie elementare Verhaltensbausteine, so genannte Aktionen, mit Hilfe von Kontroll- und Datenflüssen zu komplexerem Verhalten kombiniert werden.

## Elementare Bausteine einer Aktivität

Eine Aktivität ordnet Aktionen als elementare Verhaltensbausteine in einem Netzwerk an, das aus Knoten und Kanten besteht. Die UML2 kennt drei Typen von Aktivitätsknoten:
* Aktionen sind die elementaren Verhaltensbausteine
* Objektknoten sind Hilfsknoten, die verwendet werden, um den Fluss von Objekten durch das Netzwerk zu spezifizieren
* Kontrollknoten sind Aktivitätsknoten, die in der einen oder anderen Weise den Kontroll- oder Datenfluss in einer Aktivität steuern
Aktivitätskanten sind in zwei Hauptgruppen eingeteilt:
* ein Kontrollfluss ist eine Aktivitätskante, über die keine Objekt-Token fließen
* ein Objektfluss ist eine Aktivitätskante, über die Objekte von einem Objektknoten zum nächsten fließen können
Die Abbildung rechts zeigt ein Beispiel für die graphische Notation einer Aktivität. Verschiedene mögliche Bestandteile, zum Beispiel Formen von Objekt- und Kontrollknoten sowie Exemplare von Objekt- bzw. Kontrollflüssen sind dargestellt.

## Strukturieren von Aktivitäten

Wenn ein komplexes Verhalten als Aktivität modelliert wird, kann das entsprechende Modell und vor allem eine zugehörige graphische Darstellung in einem Aktivitätsdiagramm so umfangreich werden, dass sie nur noch schwer erfasst, vermittelt und gewartet werden kann. Es drängt sich deshalb auf, umfangreiche Aktivitäten in kleinere, übersichtlichere Teile zu gliedern. In der UML2 sind dafür zwei Techniken bekannt.

### Verschachteln

Aktivitäten können verschachtelt werden. Dabei geht man ähnlich vor, wie bei der Strukturierung eines Programms in Unterprogramme, die aus einem Hauptprogramm aufgerufen werden. Ein Teil einer umfangreichen Aktivität, das „Hauptprogramm“, wird dabei in eine eigenständige Aktivität, das „Unterprogramm“, ausgelagert. In der Hauptaktivität erscheint dann nur noch eine Aktion, die den Aufruf der Unteraktivität repräsentiert. Die UML2 stellt dafür die Aktion CallBehaviorAction zur Verfügung. Sie wird mit einem speziellen Symbol, einer stilisierten Harke, in der rechten oberen Ecke gekennzeichnet.

### Kontrollstrukturen verwenden

Die Strukturierte Programmierung fordert seit den 1960er Jahren, dass Software aus den drei elementaren Bausteinen Sequenz, Auswahl und Schleife aufzubauen sei, damit sie effizienter zu erstellen, zu testen und zu warten ist. Dieser Grundsatz wurde formuliert, um dem Einsatz der so genannten Sprunganweisung (engl. goto statement) entgegenzutreten. Man ging davon aus, dass diese und andere Technik die Softwarekrise in den 60ern mitverursacht hat. Inzwischen gelten die Grundsätze der strukturierten Programmierung in der Informatik als selbstverständlich.
Obschon die UML2 keine Programmier-, sondern eine Spezifikationssprache ist, sind Modellierer bei der Spezifikation des Verhaltens eines Systems mit ähnlichen Problemen konfrontiert wie Programmierer bei der programmtechnischen Umsetzung. Besonders trifft dies auf die Spezifikation von Verhalten mit Hilfe von Aktivitäten zu. Das Gegenstück zu den Sprunganweisungen in der klassischen Programmierung sind hier die beliebig einsetzbaren Kontroll- und Objektflüsse, die zu schlecht strukturierten Verhaltensspezifikationen führen können.
Damit anstelle der hinlänglich bekannten „Softwarekrise“ in Zukunft keine „Modellkrise“ entsteht, stellt die UML2 die aus der strukturierten Programmierung bekannten Kontrollstrukturen auch für die Modellierung von Aktivitäten zur Verfügung. Zu den so genannten strukturierten Knoten (engl. StructuredNode) gehören insbesondere
* der Sequenzknoten (engl. SequenceNode)
* der Entscheidungsknoten (engl. ConditionalNode)
* der Schleifenknoten (engl. LoopNode)
Aus der Spezifikation der UML2 geht nicht hervor, wie diese Knoten graphisch darzustellen sind. Die Abbildung verwendet die vorgeschlagene Darstellung aus UML glasklar (Lit.: Jeckle 2004). Der strukturierte Knoten wird mit einem gestrichelten, abgerundeten Rechteck gezeichnet. In diesem Beispiel handelt es sich um einen Entscheidungsknoten, der in drei Bereiche eingeteilt ist: einem Abschnitt für die Prüfung einer Bedingung („Wenn-Teil“), einem „Dann-Teil“ und einem „Sonst-Teil“.

## Semantik

Eine Aktivität modelliert ein Verhalten, indem sie indirekt festlegt, welche elementaren Aktionen in welcher Reihenfolge ausgeführt werden. Die Bedeutung einer Aktivität ist dadurch gegeben, dass zumindest gedanklich kleine Datenpakete, so genannte Token, den Aktivitätskanten entlang wandern und bei den Aktivitätsknoten etwas bewirken. Für jede Art von Aktivitätsknoten und Aktivitätskanten sind Regeln definiert, wie sie mit diesen Token umgehen, unter welchen Bedingungen sie Token zum Beispiel zwischenspeichern, zurückhalten, verdoppeln, oder einzeln bzw. als Gruppe weiterleiten. Alle Regeln zu den einzelnen Arten von Aktivitätsknoten zusammengefasst, ergeben das Regelwerk, wie eine modellierte Aktivität zu interpretieren ist, das heißt, welche Bedeutung sie hat.
Grundsätzlich orientieren sich die Regeln für den Fluss von Token in einer Aktivität an den Regeln ähnlicher formaler Modelle, wie zum Beispiel den Petri-Netzen. So gilt zum Beispiel in Analogie zu Petri-Netzen das Prinzip, dass eine Aktion in einer Aktivität dann gestartet wird, wenn an jeder eingehenden Aktivitätskante ein Token anliegt. Andererseits definiert die UML2 für den Fluss von Token durch eine Aktivität weitaus detailliertere Regeln als in Petri-Netzen. Das hat vor allem zwei Gründe. Erstens verfügen Aktivitäten über zahlreiche zusätzliche Arten von Knoten, die in Petri-Netzen nicht vorkommen. Zweitens bestimmen Eigenschaften wie die Kapazität von Aktivitätskanten und Objektknoten sowie der Streaming-Modus von Aktivitätsparameterknoten den Token-Fluss mit.
Grundsätzlich gelten für den Fluss der Token jedoch die drei folgenden Regeln:
* Zwischenspeicher nur in Objektknoten. Objektknoten, zum Beispiel Pins oder Aktivitätsparameterknoten, können Token halten. Kontrollknoten wie Entscheidungs- oder Parallelisierungsknoten dienen im Gegensatz dazu nicht als Zwischenspeicher für Token. Ein Token fließt grundsätzlich immer von einem Objektknoten zu einem anderen Objektknoten.
* Vollständige Traversierung (engl. traverse-to-completion). Quellknoten bieten Token den ausgehenden Aktivitätskanten an und ein Token wandert erst dann von einem Quellknoten entlang einer oder mehrerer Aktivitätskanten zu einem Zielknoten, wenn der ganze Weg „frei“ ist, das heißt, wenn alle beteiligten Knoten und Kanten das Token weiterleiten und wenn der End-Knoten das Token aufnehmen kann. Ein Token traversiert in diesem Fall den „freien“ Weg entweder ganz oder gar nicht. Token, die auf halbem Weg steckenbleiben, gibt es nicht.
* Token-Wettbewerb (engl. token competition). Wenn die detaillierten Regeln für Aktivitätsknoten und Aktivitätskanten ergeben, dass ein Token einen Objektknoten über mehr als eine Aktivitätskante verlassen kann, das heißt, wenn mehr als ein Weg möglich ist, dann wandert das Token über irgendeine der möglichen Kanten. Die Auswahl ist nicht festgelegt, was nicht unbedingt heißen muss, dass sie zufällig ist. Vielmehr ist es Implementationen des spezifizierten Verhaltens freigestellt, wie sie die Auswahl treffen.