UML-Sequenzdiagramme mit PlantUML erstellen
https://oer-informatik.de/uml-sequenzdiagramm-plantuml
tl/dr; (ca. 10 min Lesezeit): Mithilfe des Tools plantUML lassen sich codebasiert UML-Sequenzdiagramme erstellen. In diesem Artikel werden einige Tipps und Tricks zum Umgang mit plantUML vorgestellt.
PlantUML stellt einen einfach versionierbaren und änderbaren Weg zur Verfügung, mit OpenSource-Software UML-Diagramme zu erstellen. Diese kann auch direkt in die Dokumentationen der Repositories eingebunden werden (die Markdown-Engines von Gitlab, Github, Bitbucket & Co. unterstützen PlantUML nativ). Leider nimmt es die Referenzbeschreibung von PlantUML (plantuml.com/de/sequence-diagram) mit dem UML-Standard nicht allzu genau. Im Folgenden werden einige Tipps gegeben, wie sich mit PlantUML ansehnliche und relativ standardkonforme Sequenzdiagramme darstellen lassen.
Minimales Sequenzdiagramm mit PlantUML
PlantUML-Quelltexte beginnen mit @startuml
und enden mit @enduml
. Die Kommunikationspartner werden automatisch erkannt, wenn man mit einem Pfeil signalisiert, von wo nach wo eine Nachricht versendet werden soll. Nach einem Doppelpunkt kann der Nachrichteninhalt übermittelt werden:
Sender -> Empfänger: Nachricht
Solange der stilisierte Pfeil auf den Empfänger zeigt können die Teilnehmer auch vertauscht werden:
Eva <- Adam: Nochmal Hallo
Codebeispiel: ( online bearbeitbar / vollständiger Quelltext )
@startuml
Adam -> Eva: Hallo
@enduml

Die folgenden Diagramme wurden mit Layout-Befehlen angepasst (Details dazu im Abschnitt “Aufhübschen”, siehe unten). Um die Diagramme UML-konform zu halten sind folgende Einstellungen im Kopf nötig:
@startuml
skinparam style strictuml
hide footbox
@enduml
hide footbox
versteckt die (in der UML nicht vorgesehenen) unteren Bezeichnungsboxen der Lebenslinien,skinparam style strictuml
ersetzt die halboffenen Pfeilspitzen bei synchronen Nachrichten durch geschlossenen ausgefüllte - wie im Standard vorgesehen.
Kommunikationspartner darstellen mit Plantuml
Sofern die Kommunikationspartner (Lebenslinien) ein besonderes Symbol erhalten sollen (in UML nicht so vorgesehen), einen Namen mit Freizeichen bekommen (z.B. wie es z.B. bei objektinstanzname: Klassenname
der Fall ist) oder eine bestimmte Reihenfolge sichergestellt werden soll, werden die Kommunikationspartner vorab deklariert. Die Deklaration wird wie folgt notiert:
SYMBOLTYP "NameImDiagramm" as ALIASNAME
Codebeispiel: ( online bearbeitbar / vollständiger Quelltext )
participant frontend
participant ":Backend" as backend
actor "martin :User" as martin
database "db :Datenbank" as db
collections "liste :Collection" as liste

Synchrone Nachrichten und aktive Lebenslinien
Man unterscheidet aktive (als Rechteck gezeichnete) und passive (gestrichelte / als Linie gezeichnete) Lebenslinien. PlantUML löst dies durch die Befehle activate LEBENSLINIENNAME
und deactivate LEBENSLINIENNAME
. So lange eine Akteurin selbst etwas ausführt oder auf die Antwort einer anderen Teilnehmerin wartet ist sie aktiv.
Bei Nachrichten unterscheidet die UML zwischen synchronen und asynchronen Nachrichten. Bei Synchronen Nachrichten wartet die Absenderin darauf, dass die Empfängerin die Nachricht vollständig bearbeitet hat (z.B. die aufgerufene Methode beendet wurde). Es kann (muss aber nicht) eine Antwort auf eine synchrone Nachricht folgen (bei Methodenaufrufen: Rückgabewert). Notiert wird die Nachricht mit einem durchgezogenen Pfeil mit ausgefüllter Pfeilspitze:
Absender -> Empfänger: SynchroneNachricht
Die Antwort wird als gestrichelte Linie mit offener Pfeilspitze notiert, was in PlantUML folgendermaßen angegeben werden muss:
Absender <<-- Empfänger: AntwortAufSynchroneNachricht
Codebeispiel: ( online bearbeitbar / vollständiger Quelltext )
activate starter
starter -> meinKonto: setName("Hannes")
activate meinKonto
deactivate meinKonto
starter -> meinKonto: getName()
activate meinKonto
starter <<-- meinKonto: getName(): "Hannes"
deactivate meinKonto
starter -> meinKonto: getKontoNr()
activate meinKonto
starter <<-- meinKonto: "123456"
deactivate meinKonto
deactivate starter

Asynchrone Nachrichten
Bei Parallelisierung sind Nachrichten i.d.R. asynchron: die Absenderin wartet nicht darauf, dass eine Nachricht bearbeitet wurde und geht unmittelbar zur nächsten Aktion über. In der UML werden diese Nachrichten mit einer offenen Pfeilspitze notiert.
Asynchrone Nachrichten haben per Definition keine Antwortnachricht. Reaktionen auf asynchrone Nachrichten werden als neue selbständige asynchrone Nachrichten notiert.
Codebeispiel: ( online bearbeitbar / vollständiger Quelltext )
starter ->> meinThread1:start()
activate meinThread1
starter ->> meinThread2:start()
activate meinThread2
starter <<- meinThread2:Bearbeitung beendet
deactivate meinThread2

Nachrichten ohne Absender / Empfänger
Sofern der Absender / Empfänger einer Nachricht für die betreffende Modellierung nicht relevant ist (oder unbekannt ist) spricht man von gefundenen (FoundMessage) bzw. verlorenen Nachrichten (LostMessage). Sie starten bzw. enden nicht an Lebenslinien, sondern an einem ausgefüllten Punkt. Ausgefüllt lässt sich dieser leider mit PlantUML nicht darstellen. Befehlsweise kann diese Notation genutzt werden (nicht ausgefüllter Punkt):
Codebeispiel: ( online bearbeitbar / vollständiger Quelltext )
'am besten geeignet, nur Ausfüllung fehlt
[o->> webserver: HttpGetRequest("www.beispiel.de")
webserver ->>o] : HttpResponse: "<html>...</html>"
'verloren nach / gefunden von links
[o->> webserver: HttpGetRequest("www.beispiel.de")
?<<-o webserver: HttpResponse: "<html>...</html>"
'verloren nach / gefunden von rechts
webserver o<<-? : Log aktiviert
webserver ->>o] : Zugriff loggen

Um zu signalsieren, dass die Nachrichten im Nichts landen, wird in PlantUML an Stelle eines fehlenden Kommunikationspartners entweder das Ende des Diagramms angegeben (“[
” bzw “]
”), oder einfach das Ende des Pfeils (dessen Länge vom Nachrichtentext abhängt (mit ?
). In einigen Fällen werden die Kreise an den Pfeilenden nicht mehr komplett dargestellt, dann ist es ggf. erforderlich etwas mit dieser nicht ganz eingängigen Notation zu spielen. Beispiele, wie die Lösung aussehen kann finden sich oben.
Objekterzeugung / Erzeugungsaufruf
Objekterzeugungsaufrufe werden in der UML notiert wie Antworten auf synchrone Nachrichten: gestrichelte Linie und offene Pfeispitze. In plantUML wird dieser Antwort notiert (starter -->> meinKonto: new()
) und ein create
vorangestellt:
Codebeispiel: ( online bearbeitbar / vollständiger Quelltext )
@startuml
participant "StarterKlasse" as starter
activate starter
participant "meinKonto :Konto" as meinKonto
create meinKonto
starter -->> meinKonto: new()
deactivate starter
@enduml

Objektdekonstruktion
Dekonstruktionsnachrichten sind normale (synchrone oder asynchrone) Nachrichten, die das aufgerufene Objekt zerstören (je nach Programmiersprache: den Dekonstruktor aufrufen, Referenz auf NULL legen…). Die Zerstörung wird notiert, in dem an das Ende der Lebenslinie ein “X” geschrieben wird. In PlantUML wird destroy meinKonto
notiert:
Codebeispiel: ( online bearbeitbar )
starter -> meinKonto: kontoAufloesen()
activate meinKonto
deactivate meinKonto
destroy meinKonto

Selbstnachrichten
Nachrichten kann jeder Teilnehmer auch an sich selbst schicken (Methodenaufrufe eines Objekts auf sich selbst). Absenderin und Empfängerin sind dann identisch.
Codebeispiel: ( online bearbeitbar / vollständiger Quelltext )
konto->konto : getKontostand()
activate konto
konto<<--konto : getKontostand():123,45
deactivate konto

Schleifen im Sequenzdiagramm
Schleifen werden im UML-Sequenzdiagramm über kombinierte Fragmente dargestellt. Im Fall einer Wiederholung über das Schlüsselwort loop
in Kombination mit einem guard (im einfachsten Fall der Anzahl der Schleifendurchläufe oder einer Bedingung, bis zu deren zutreffen der Schleifenrumpf ausgeführt wird).
Codebeispiel: ( online bearbeitbar / vollständiger Quelltext )
group loop (verzinsungsJahre)
konto -> konto: guthaben = verzinse(guthaben, zinsatz)
activate konto
konto <<-- konto: guthaben = verzinse(): guthaben + zins
deactivate konto
end

Bedingte Anweisungen im Sequenzdiagramm
Auch bedingte Anweisungen werden als kombiniertes Fragment dargestellt. Der guard (die Bedingung) wird von PlantUML mit eckigen Klammern umgeben, so dass die Notation einfach wie folgt ist:
alt BEDINGUNG
else else
end
Das zweite else
taucht als guard im Diagramm auf. Falls ein elseif
-Block folgen soll würde else BEDINGUNG
notiert.
Codebeispiel: ( online bearbeitbar / vollständiger Quelltext )
alt bestandskunde(Kunde) == true
Kunde <<-- Bank: true
else else
Bank -> Schufa: istSolvent(Kunde)
activate Schufa
Bank <<-- Schufa : schufaErgebnis
deactivate Schufa
Kunde <<-- Bank: schufaErgebnis
deactivate Bank
end

Concurrency - Parallelisierung im Sequenzdiagramm
Wenn mehrere Interaktionen parallel verlaufen wird dies mit dem kombinierten Fragment par
notiert.
par
INTERAKTION
else
PARALLELEINTERAKTION
end
Codebeispiel: ( online bearbeitbar / vollständiger Quelltext )
activate Browser
par
Browser -> Webserver: lade("hintergrundbild.gif")
activate Webserver
Browser <<-- Webserver: lade("hintergrundbild.gif"):file
deactivate Webserver
else
Browser -> Webserver: lade("titelbild.gif")
activate Webserver
Browser <<-- Webserver: lade("titelbild.gif"):file
deactivate Webserver
end
deactivate Browser

Referenzen: Auslagern von Abschnitten in weitere Sequenzdiagramme
Zur Übersichtlichkeit können Sequenzdiagrammme aufgeteilt und ineinander referenziert werden. In PlantUML wird dies über das Schlüsselwort ref
umgesetzt, wobei die zu überdeckenden Lebenslinien als kommagetrennte Liste angefügt werden.
ref over nameLebenslinie1, nameLebenslinie2 : nameDesReferenziertenSequenzdiagramms
Codebeispiel: ( online bearbeitbar / vollständiger Quelltext )
activate client1
client1 -> cs:setState(someState)
activate cs
ref over co1, cs : changeState
client1 <<-- cs:void
deactivate cs
deactivate client1

Der referenzierte Bereich wird dann an anderer Stelle in einem Interaktionsrahmen als eigenes Diagramm angegeben. PlantUML nutzt hierfür das Schlüsselwort mainframe
. Der UML-Standard erwartet, dass dem Namen des Interaktionsrahmens sd
(für sequence diagram) vorangestellt wird. Beispiel:
mainframe sd nameDesDiagramms
Codebeispiel: ( online bearbeitbar / vollständiger Quelltext )
mainframe sd changeState
participant "subject :Subject" as cs
participant "observer1 :ConcreteObserver" as co1
activate cs
|||
deactivate cs

Weitere kombinierte Fragementen
UML-Sequenzdiagramme sehen eine Reihe weiterer kombinierter Fragmente vor, die in Plantuml über die folgende Notation umgesetzt werden:
group opt
client-> server:request()
end
Neben dem hier gewählten opt können beliebige ander Zeichenketten genannt werden (strict, assert, critical wären z.B. in der UML noch vorgesehen).
Zeitliche Zusicherungen
Sofern die Abfolge von Nachrichten an bestimmte zeitliche Zusicherungen gebunden ist, können dies im Diagramm angegeben werden. PlantUML nutzt dafür Label, die in geschweiften Klammern angegeben un den Nachrichten vorangestellt werden.
Zeitdauern zwischen Label können dann unter der jeweiligen Zusicherung, die als guard nach UML-Notation in geschweiften Klammer stehen muss, angegeben werden. Da dies nur mit der neuen PlantUML-Engine teoz
dargestellt werden kann, muss diese derzeit noch vorneweg über den Befehl !pragma teoz true
aktiviert werden:
!pragma teoz true
{ChangeStateStartLabel} client1 -> cs:setState(someState)
activate cs
{ChangeStateStopLabel} client1 <<-- cs:void
deactivate cs
{ChangeStateStartLabel} <-> {ChangeStateStopLabel} : {500ms}
Codebeispiel: ( online bearbeitbar / vollständiger Quelltext )

plantUML-Webservice zur Diagrammerzeugung nutzen
PlantUML bietet einen Webservice, der Diagramme unmittelbar online rendert.
Variante 1: Codierter Quelltext: PlantUML kodiert den Quelltext, um ihn so über den Webservice zugänglich (und bearbeitbar) zu machen. Die URL ist in diesem
Fall wie folgt aufgebaut:
http://www.plantuml.com/plantuml/AUSGABEFORMAT/CODIERTERQUELLTEXT
wobei als AUSGABEFORMAT
png
,svg
,eps
,epstext
undtxt
genutzt werden kann. Wird als AUSGABEFORMATuml
gewählt erhält man den bearbeitbaren Quelltext.Editierbare Links lassen sich auch über den Service von planttext.com erstellen, sie nutzen die selbe Quelltextcodierung und URLs nach dem Muster: https://www.planttext.com/?text=CODIERTERQUELLTEXT Auch in den erzeugten PNG-Dateien wird der codierte Quelltext als Titel hinterlegt, so dass sie sich relativ einfach später weiterverarbeiten lassen.
Variante 2: Quelltext direkt online rendern: der PlantUML-Quelltext ist online als Resource verfügbar und soll gerendert ausgegeben werden. Hierzu muss eine URL nach dem Muster:
http://www.plantuml.com/plantuml/proxy?fmt=AUSGABEFORMAT&src=https://URL_PLANTUMLSOURCE
erstellt werden, wobei als AUSGABEFORMAT
png
,svg
,eps
,epstext
undtxt
genutzt werden kann. Diese Funktion scheint derzeit deaktiviert zu sein oder nur Entwicklern vorbehalten.
plantUML-Formatierung: Aufhübschen von Sequenzdiagrammen
Über Skins bietet PlantUML die Möglichkeit die Diagramme in Schriftart, Farben und Aussehen individuell anzupassen. An drei Beispielen soll das hier kurz gezeigt werden, wie die Konfiguration mit skinparam
das Aussehen der Sequenzdiagramme individualisieren kann.
Darstellung ohne zusätzliche skinparam
-Befehle
Ein Auszug aus dem Observer-Pattern sieht ohne Anpassungen des Skins mit PlanUML folgendermaßen aus:
Beispiel: ( online bearbeitbar / vollständiger Quelltext )

Skin mit angepassten Farben und näher am UML-Standard
Im folgenden Beispiel (das für die Diagramme oben verwendet wurde) wurde kosmetisch nur Farben und Schriftart anpasst, aber zusätzlich auch die oben genannten Tipps verwendet, um das Diagramm UML-konformer erscheinen zu lassen: skinparam style strictuml
für die Pfeile und hide footbox
für die Enden der Lebenslinien.
Codebeispiel: ( online bearbeitbar )
@startuml
skinparam style strictuml
skinparam DefaultFontName "Lucida Sans Typewriter"
skinparam sequence {
ArrowColor DarkSlateBlue
ActorBorderColor DarkSlateBlue
ActorBackgroundColor whitesmoke
LifeLineBorderColor DarkSlateBlue
LifeLineBackgroundColor whitesmoke
ParticipantBorderColor DarkSlateBlue
ParticipantBackgroundColor whitesmoke
}
skinparam Note{
BorderColor DarkSlateBlue
BackgroundColor LightYellow
}
skinparam Database{
BackgroundColor whitesmoke
BorderColor DarkSlateBlue
}
skinparam Collections{
BackgroundColor whitesmoke
BorderColor DarkSlateBlue
}
hide footbox
'[...]
@enduml

Sequenzdiagramme per Formatierung als Entwurf kennzeichnen
Um den Entwurfscharakter eines Sequenzdiagramms zu unterstützen kann ein Layout verwendet werden, dass Handschrift ähnelt. Besonders wirkungsvoll ist das, wenn auch die Schrift authentisch handschriftlich aussieht. Dies ist z.B. bei der Schriftart “FG Virgil” der Fall. Welche Schriften das jeweilige System bietet lässt sich mit dem PlantUML-Befehl listfonts
anzeigen. Wichtig ist: sofern eine Vektorgrafik ausgegeben wird (svg, eps) muss die Schrift auf allen anzeigenden Computern vorhanden sein, andernfalls werden Ersatzschriftarten verwendet.
Beispiel: ( online bearbeitbar / vollständiger Quelltext )
skinparam style strictuml
skinparam DefaultFontName "FG Virgil"
skinparam handwritten true
skinparam monochrome true
skinparam packageStyle rect
skinparam shadowing false

Diagramme vereinheitlichen und Formatierung auslagern
Damit nicht alle PlantUML-Diagramme die selben skinparam
-Sequenzen am Beginn der plantUML-Datei nennen müssen, kann eine zentrale Konfigurationsdatei eingebunden werden, die die Formatierungen enthält:
!includeurl https://PATH.TO/MY/UMLSEQUENCE_CONFIG.cfg
Alle Befehle in dieser Datei werden ausgeführt, als stünden sie in der umgebenden PlantUML-Datei. Um ein einheitliches Layout zu erreichen ist diese Funktion sehr praktisch!
Links und weitere Informationen
Es finden sich zahlreiche Quellen und Dokumentationen zu PlantUML im Netz, erwähnenswert sind u.a.:
Quellen und offene Ressourcen (OER)
Die Ursprungstexte (als Markdown), Grafiken und zugrunde liegende Diagrammquelltexte finden sich (soweit möglich in weiterbearbeitbarer Form) in folgendem git-Repository:
https://gitlab.com/oer-informatik/uml/umlsequenz.
Sofern nicht explizit anderweitig angegeben sind sie zur Nutzung als Open Education Resource (OER) unter Namensnennung (H. Stein, oer-informatik.de) freigegeben gemäß der Creative Commons Namensnennung 4.0 International Lizenz (CC BY 4.0).