Hitchhiker’s Guide to Docs-As-Code: Diagramme, aber richtig…

©S&S Media
Architekturdokumentation besteht hauptsächlich aus Fließtext, Tabellen und Diagrammen. Fließtext und Tabellen sollten nach der letzten Folge kein Problem mehr sein. Jetzt zeigen wir Ihnen mehrere Optionen, Diagramme in Ihre Dokumentation zu integrieren: Einerseits den einfachen Weg des Referenzierens (mit einigen möglichen Optionen) und alternativ Diagrams-as-Code, was gut zu Titel und Inhalt dieser Kolumne passt. So viel sei allerdings schon verraten: Leider eignet sich der letztgenannte (PlantUML-basierte) Ansatz nur für ganz wenige Arten von Diagrammen. Aber eins nach dem anderen – fangen wir mit den einfachen Dingen an.
Diagramme verwenden
Mit verwenden meinen wir in der Regel die Integration eines Diagramms, das als eigenständige Grafikdatei (etwa als .jpg, .png oder .svg) existiert, in unsere AsciiDoc-basierte Dokumentation. Diese Grafik muss zum Build-Zeitpunkt an einem definierten Platz (dem sogenannten images-Directory) vorliegen. Zu unserem Diagramm oder Bild hätten wir gerne eine Unterschrift sowie eine fortlaufend vergebene Bild/Diagramm-Nummer. Wie einfach die AsciiDoc-Lösungen dafür aussieht, zeigen wir am Beispiel eines (noch nicht) weltbekannten Logos. Abbildung 1 enthält eine Vorschau auf das Ergebnis.
.Das HHGDAC-Logo
image::hhgdac-logo.png["alternate-text"]
Styling ist alles (oder?)
Ach ja, bei Bedarf möchten Sie Ihre Diagramme etwas stylen, etwa Größe und Ausrichtung anpassen, mehrere Diagramme nebeneinander zeigen und das englische Wort Figure durch Abbildung ersetzen. Auch dafür hat AsciiDoc einfache Mittel an der Hand (Listing 1). Wir haben unser Logo in drei verschiedenen Größen verwendet, und verwenden als Bild-Unterschrift jetzt Abbildung. Mit der figure-caption benennen wir die Standard-Bildunterschrift um. Bei jedem Diagramm geben wir an, ob es links-, rechtsbündig oder zentriert angezeigt werden soll. Das können wir innerhalb der [] nach dem Dateinamen schreiben, oder vor dem eigentlichen image-Tag. In die float-group können Sie auch noch Textabsätze aufnehmen, die stellt AsciiDoc dann neben die entsprechenden Bilder. Das ist manchmal ganz nützlich, wenn Sie neben (schmalen) Abbildungen noch erläuternden Text platzieren möchten.
Vorsicht: Nutzen Sie Styling-Anweisungen nur in Ausnahmefällen, weil das gegen die gute Idee der Trennung von Inhalt und Layout verstößt! Wir finden es allerdings nützlich, über diese Optionen zu verfügen, sie könnten (Konjunktiv!) ja mal hilfreich sein. In HTML funktionieren diese Styling-Optionen gut, in anderen Formaten (epub, confluence oder auch pdf) nur sehr eingeschränkt [1].
:figure-caption: Abbildung [.float-group] -- .Logo 150px image::hhgdac-logo.png[float="left", 150] .Logo 100px image::hhgdac-logo.png[float="left",100,75] [.left] .Logo 75px image::hhgdac-logo.png[width=75] --
Bilder aus der Ferne
Manchmal (aber ziemlich selten) ist es für Dokumentation auch hilfreich, Bilder oder Diagramme zu verwenden, die zur Build-Zeit noch nicht vorhanden sind, etwa die beliebten Badges. Unserer Ansicht nach sollten Sie dieses Feature mit Vorsicht einsetzen, und möglichst auf Online-Dokumentation (beispielsweise die readme-Datei Ihres Github-Repositories) beschränken. AsciiDoc erledigt das auf ganz logische Weise, nämlich über die Angabe der URL anstelle des reinen Dateinamens. Das Beispiel zeigt drei so genannte Badges, diesmal als inline-images (nur ein : nach dem image-Tag) verpackt, damit sie brav nebeneinander stehen. Abbildung 3 zeigt wieder das Ergebnis.
image:http://img.shields.io/travis/aim42/aim42/master.svg[float="left"]
image:http://img.shields.io/github/issues/aim42/aim42.svg[float="left"]
image:https://img.shields.io/github/stars/aim42/aim42.svg[float="left"]
Auf Diagramme verweisen
Jetzt, da wir Diagramme einfach verwenden können, möchten wir von anderen Stellen unserer Architekturdokumentation aus natürlich auf diese Diagramme verweisen. Am einfachsten geht das durch die Definition einer Referenz- oder Sprungmarke, der [[img-ref-example]]:
[[img-ref-example]]
.Das HHGDAC-Logo
image::hhgdac-logo.png[]
Auf diesen Bezeichner können Sie anschließend an jeder beliebigen Stelle im Text mit <<img-ref-example>> verweisen, wobei AsciiDoctor diese Sprungmarke automatisch durch die verwendete Bildunterschrift ersetzt. In diesem Fall also das HHGDAC-Logo. Durch welchen Text AsciiDoctor die Sprungmarke genau ersetzt, können Sie mit mit dem Attribut :xrefstyle: steuern. In diesem Beispiel wird durch :xrefstyle: full die volle Bildunterschrift angegeben, also Abbildung 1. Das HHGDAC Logo :xrefstyle: short gibt nur die Bildnummer an, also Abbildung 1 und :xrefstyle: basic nur den beschreibenden Teil der Bildunterschrift, also das HHGDAC Logo. Dabei setzen Sie das Attribut entweder im build.gradle in der Liste der Attribute oder direkt in Ihrer AsciiDoc-Datei als :xrefstyle: full.
Diagramme als Text
Im Sinne von Docs-as-Code können wir noch weitergehen und Diagramme als Text beschreiben. PlantUML [2] ist wohl das bekannteste Open-Source Werkzeug, um dieses Ziel zu erreichen. Dieser Ansatz ermöglicht es zumindest theoretisch, die visuelle Darstellung der Architektur als Text zu verwalten (unseren Kommentar zur Nützlichkeit finden Sie im Textkasten). Ein einfaches Beispiel sieht wie in Listing 2 und Abbildung 4 dargestellt aus.
Jede Diagrammbeschreibung beginnt mit @startuml und endet mit @enduml. Die darauf folgende Zeile definiert, dass Komponenten in der UML2-Notation dargestellt werden sollen. Wem das egal ist, kann diese Definition auch weglassen. Die folgenden drei Zeilen definieren Typ, Bezeichner und Alias der darzustellenden Elemente. Wird der Alias weggelassen, so kann man die Elemente auch über den Bezeichner Referenzieren. Die letzten zwei Zeilen definieren die Beziehungen zwischen den Elementen. Das Ergebnis kann sich sehen lassen.
Tipp: Diagramme mit PlantUML
Auch komplexere Diagramme lassen sich mit PlantUML darstellen, wie ein Selbstversuch zeigt [3]. Sie lassen sich aber nur schwer verwalten, denn die Textdarstellung wird schnell unübersichtlich und die Diagramme enthalten versteckte Layoutinformationen. Das im Selbstversuch erzeugte Diagramm resultierte aus einer Vorlage. Das Layout wurde mit entsprechenden Hinweisen an PlantUML wie -down-> umgesetzt. Umgekehrt wäre ein Design eines solch komplexen Diagramms umständlich. Eine Ausnahme bilden jedoch die Sequenzdiagramme. Ihre Darstellung bleibt auch in der Textform übersichtlich und das automatische Layout ist sogar gegenüber anderen, graphischen Tools sehr angenehm.
@startuml skinparam componentStyle uml2 file document.adoc as input file document.html as output component asciidoctorj input -> asciidoctorj asciidoctorj -> output @enduml
Um das ganze in AsciiDoc einzubetten, gibt es drei Möglichkeiten, inline, include oder per Makro. Die beiden @startuml- und @enduml-Marker können dabei entfallen. Der Dateityp .png hat sich für viele Ausgabeformate bewährt. Wichtig ist jedoch, dass man den zweiten Parameter des PlantUML-Blocks in AsciiDoc variiert. Das ist der Dateiname unter dem die Grafik zwischengespeichert und bei gleichen Namen auch überschrieben wird. Apropos zwischenspeichern: die meisten Text-Editoren mit PlantUML-Vorschau generieren die Diagramme gleich im imagesdir. Da man die Diagramme ja generieren und nicht unter Versionskontrolle stellen möchte, bietet es sich an, wie in Listing 3 gezeigt, den Pfad für die generierten Diagramme umzuleiten und dann im .gitignore entsprechend aus der Versionierung zu nehmen. Dies ermöglicht es auch, das Verzeichnis bei der Generierung eines PDFs umzubiegen. Das ist leider notwendig, da das PDF-Plugin die PlantUML-Diagramme an anderer Stelle sucht [].
ifndef::imagesdir[:imagesdir: ./images] ifndef::plantUMLDir[:plantUMLDir: .plantuml/] //inline .Ein einfaches Komponentendiagramm [plantuml, "{plantUMLDir}plantuml-demo1”, “png”] ---- skinparam componentStyle uml2 component asciidoctorj as adj component docToolChain as dtc file AsciiDoc as input file html file pdf file confluence file many_more input -> adj adj -> dtc : "html,\ndocbook" adj --> html adj --> pdf dtc --> confluence dtc --> many_more ---- //referenziert [plantuml,"{plantUMLDir}plantuml-demo2",png] ---- include::sequences/demo.puml[] ---- //noch kürzer per Makro plantuml::sequences/demo.puml["{plantUMLDir}plantuml-demo3"]
Da Sie bei PlantUML nur geringen Einfluss auf das Layout, also die Anordnung der Elemente des Diagramms haben, eignet sich dieser Ansatz vor allem für Darstellungen, bei denen das Layout entweder eine geringe Rolle spielt oder von PlantUML perfekt umgesetzt wird. Unserer Erfahrung nach trifft dies einerseits auf einfache statische Diagramme, aber hauptsächlich auf Sequenzdiagramme zu. Wie man mit dem Layout dennoch ein wenig tricksen kann, zeigt Hubert A. Klein Ikkink in seinem Blog [4][5].
Die textuelle Repräsentation von Sequenzdiagrammen bringt den weiteren Vorteil mit, dass sich verschiedene Variationen von Abläufen durch erzeugen und im Team diskutieren lassen (Listing 4 und Abbildung 6). Anschließend können Sie mit konventionellen merge-Mitteln die Resultate zusammenführen.
.Sequenzdiagramm [plantuml,”seq1”,png] ---- actor Benutzer Benutzer -> Browser Browser -> Server Server -> Datenbank Server <-- Datenbank Browser <-- Server Benutzer <-- Browser ----
Praktische Informationen zur inhaltlichen Gestaltung Ihrer Diagramme finden Sie in den arc42 FAQs [6] und im C4-Modell von Simon Brown [7].
Fazit
Nicht nur Dokumente, sondern auch Diagramme lassen sich wie Code verwalten. Komplexere Diagramme können Sie, wie in der letzten Folge beschrieben, als Grafik referenzieren. Über die Referenzierung lassen sich die Diagramme leichter aktualisieren, aber sie müssen immer noch aus dem eigentlichen Modellierungstool exportiert werden. Hier zeigt Gradle seine Stärke. Diese setzen wir im nächsten Teil der Serie ein, um Diagramme direkt aus UML-Modellierungswerkzeugen zu exportieren.
[1] Handbuch Styling-Optionen: http://asciidoctor.org/docs/user-manual/#sizing-images
[2] Open-Source Werkzeug zur Generierung von UML-Diagrammen aus einer einfachen textuellen DSL: http://plantuml.com/.
[3] Diagramme mit PlantUML: https://rdmueller.github.io/plantUML-revisited/
[4] Hubert A. Klein Ikkinks Blog: http://mrhaki.blogspot.de/2017/10/plantuml-pleasantness-layout-elements.html
[5] Hubert A. Klein Ikkinks Blog: http://mrhaki.blogspot.de/2016/12/plantuml-pleasantness-keeping-elements.html
[6] arc42: https://faq.arc42.org/home/
[7] C4-Modell von Simon Brown: https://c4model.com/
[8] doctoolchain: https://github.com/docToolchain/docToolchain
Hinterlasse einen Kommentar