Textbasierte Erstellung von UML-Diagrammen mit PlantUML

Bei komplexen Software-Systemen an denen mehrere Personen, Teams oder Unternehmen beteiligt sind, kann es bei schwammiger Kommunikation zu Missverständnissen kommen. Dies kann bedeuten, dass das geplante System sich verzögert, teurer wird oder das Projekt scheitert. Eine gemeinsame Sprache, welche für die Darstellung eines Software-Systems geeignet ist, wirkt dem entgegen. Dies wäre bspw. UML.

In diesem Artikel befassen wir uns mit der Erstellung von UML-Diagrammen mit PlantUML und VS Code. PlantUML ist ein quelloffenes Projekt, welches das Erstellen von UML-Diagrammen aus textbasierten Dateien ermöglicht. Dadurch lässt sich dessen Entwicklungsverlauf besser in Repositories nachvollziehen. Es bietet die Möglichkeit die Diagramme lokal oder zentral zu rendern.

Entwicklungsumgebung

  • Windows 10 21H2 (Build 22000.556)
  • VS Code 1.66.1
  • Java Runtime Environment
  • VS Code PlantUML Extension

Es gibt mehrere Wege PlantUML mit VS Code zu nutzen. Wir nutzen das plantuml.jar, welches von der Extension mitgeliefert wird.

Klassendiagramm

In diesem Artikel wird prototypisch der 3.0-hackathon-Branch des pluginkollektiv/antispam-bee-Repositories teilweise modelliert. Die Arbeiten wurden am 10.04.2022 um 14:29 Uhr begonnen. Je nachdem, wann dieser Artikel gelesen wird, kann es sein, dass dieser Branch nicht mehr existiert oder das Klassendiagramm nicht mehr aktuell ist.

Ein Klassendiagramm besteht aus einer .plantuml-Datei. Es fängt mit @startuml an und endet mit @enduml. Dazwischen befindet sich dessen Inhalt. Das Rendern kann über unterschiedliche Wege erfolgen. Meistens wird das Diagramm nach dem Speichern automatisch im Vorschaufenster aktualisiert. Sollte das nicht geschehen könnt ihr Shift + STRG + P drücken und PlantUML: Aktuelle Diagramm exportieren auswählen oder den Kurzbefehl Alt + D dafür benutzen. Nachfolgend seht ihr ein minimales Code-Beispiel, welches eine Ausgabe erzeugt.

@startuml class Minimal {} @enduml
Code-Sprache: CSS (css)

Bei der objektorientierten Programmierung in PHP werden auch Interfaces und Traits verwendet. Implementiert eine Klasse diese, wird dies mit dem Schlüsselwort implements angegeben. Es gibt in PlantUML keinen Pendant für PHP-Traits. Das Preprocessing-Feature wurde genutzt, um Traits besonders auszuzeichnen. Nachfolgend das Code-Beispiel:

@startuml !function trait($name) !return "class " + $name + " << (T,#FF7700) >>" !endfunction interface Verifiable {} trait(IsActive) {} class Rule implements Verifiable, IsActive {} @enduml
Code-Sprache: CSS (css)
Eine Klasse implementiert ein Interface und ein Trait

Für das folgende Beispiel wurden alle Klassen erfasst und einige Interfaces implementiert. Gibt es viele Abhängigkeiten zu einer bestimmten Klasse bzw. einem Interface oder Trait, kann die Übersichtlichkeit deutlich darunter leiden. Abhilfe schafft ein geringerer Detailgrad, der ähnlich beschreibend ist. In solchen Situationen sollte man auch andere Lösungen abwägen. Das Code-Beispiel zu dieser Ausgabe ist nur im Repository zu finden.

Unübersichtliches detailliertes Diagramm

Nach einer Reduzierung des Detailgrades konnte die Übersichtlichkeit deutlich gesteigert werden.

Übersichtlichere, weniger detaillierte Variante
@startuml Antispam Bee !function trait($name) !return "class " + $name + " << (T,#FF7700) >>" !endfunction interface Verifiable {} interface Controllable {} trait(InitRule) {} trait(IsActive) {} class ControllableRule extends Rule implements Controllable {} class Rule implements Verifiable, InitRule, IsActive {} @enduml
Code-Sprache: JavaScript (javascript)

Bisher wurde in den Beispielen noch kein Namespace verwendet. Einen solchen anzugeben ist mit dem namespace-Schlüsselwort möglich. Nachdem die Namespaces hinzugefügt wurden sehen das Diagramm und der Code dazu wie folgt aus:

@startuml Antispam Bee !function trait($name) !return "class " + $name + " << (T,#FF7700) >>" !endfunction namespace AntispamBee.Interfaces { interface Verifiable {} interface Controllable {} interface PostProcessor {} } namespace AntispamBee.Rules { trait(InitRule) {} trait(IsActive) {} class ControllableRule extends Rule implements AntispamBee.Interfaces.Controllable {} class Rule implements AntispamBee.Interfaces.Verifiable, InitRule, IsActive {} } namespace AntispamBee.PostProcessors { trait(InitPostProcessor) {} trait(IsActive) {} class PostProcessor implements AntispamBee.Interfaces.PostProcessor, InitPostProcessor {} class ControllablePostProcessor implements AntispamBee.Interfaces.Verifiable, IsActive {} } @enduml
Code-Sprache: JavaScript (javascript)

Das UML-Diagramm kann durch das Hinzufügen von Methoden und Eigenschaften erweitert werden. Auch hier kann es bei sehr großen Klassen unübersichtlich werden. Nachfolgend wird gezeigt, wie man Methoden und Eigenschaften hinzufügt und wie das Ergebnis aussieht.

@startuml class Example { {static} + public_static_method() + public_method() - private_method() # protected_method() CONCRETE_CONST = 'Really concrete' + public_static_property: int + public_property: string - private_property: array # protected_property: object } @enduml
Code-Sprache: PHP (php)
Eine Klasse mit Methoden und Eigenschaften

Wie bereits erwähnt, kann sich die Übersichtlichkeit je nach Detailgrad und Komplexität stark verringern. Um das Klassendiagramm-Beispiel abzuschließen, schauen wir uns eine Version an, in der die Rules, PostProcessors und die benötigten Interfaces und Helper-Klassen mit Methoden und Eigenschaften dargestellt werden. Das Code-Beispiel dazu findet man im Repository.

Beispiel für Rules und PostProcessors mit benötigten Interfaces und Helper-Klassen

Nun würde mich interessieren, wie ihr Missverständnisse vermeidet und Anforderungen an ein komplexes Software-System mit allen Beteiligten sicher kommuniziert. Hinterlasst mir doch dazu ein Kommentar!

References

3 Kommentare

  1. Da ich oft mit MarkDown arbeite und gern Diagramme ohne zusätzlichen Build Schritt einbette, verwende ich MermaidJS (https://mermaid-js.github.io/) für Diagramme jeglicher Art.

    Mit Mermaid kann man alle möglichen Diagramm Typen in Text Form (so auch State, Diagramme, ER Diagramme, Flow Charts und vieles mehr) erzeugen. Teilweise ist Mermaid sogar PlantUML kompatibel (zb. für State Charts). Natürlich gibts auch VSCode Extensions für Mermaid.

    Und: Mermaid Diagramme werden auch direkt in GitHub README Files und WIKI pages gerendert ohne dass man was dafür tun (aka Build Schritt) muss

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.