TL;DR
Architekturdokumentation ist sinnvoll, weil sie eine Reflexion über das Projekt erfordert.
Templates für Architekturdokumentation geben bewährte Inhalte und Strukturen vor. Eine kompakte Variante davon ist ein Canvas.
Architecture Decision Records (ADRs) beschreiben einzelne Entscheidungen und lassen sich gut mit weiterer Dokumentation kombinieren.
Diverse Tools helfen dabei, die Dokumentation automatisiert zu erstellen und zu pflegen.
Dieser Artikel möchte Entwickler:innen Ansätze und Ideen aufzeigen, die helfen, mit vernünftigem Aufwand zu guter Architekturdokumentation zu gelangen. Immer wieder treffe ich Entwicklungsteams, welche die Architektur ihrer Systeme nur schlecht oder gar nicht dokumentieren. Dabei lohnt sich Architekturdokumentation nur schon, weil sie hilft, über das eigene System nachzudenken. Sie bietet einen Überblick über Strukturen und Zusammenhänge und erläutert Konzepte und Entscheidungen, nach denen man das System baut. Speziell bei komplexen Sachverhalten wie Interaktionen mit Nachbarsystemen oder fachlichen Prozessen hilft sie, Vorgänge zu verstehen, die aus der Implementierung oft nicht nachvollziehbar sind. Weiter hilft Dokumentation, Missverständnisse zu entdecken und schützt davor, wichtige Dinge nicht mehr zu wissen, etwa aufgrund personeller Wechsel oder weil Dinge vergessen gehen. Schließlich ist die Reflexion beim Dokumentieren eine gute Gelegenheit, Verbesserungspotential zu identifizieren.
Dokumentieren ist anspruchsvoll
Die Pflege einer Architekturdokumentation ist aber anspruchsvoll und mit Aufwand verbunden, vor allem, wenn das Team vieles an einem System und der Architektur verändert. Hinzu kommt, dass die Dokumentation in solchen intensiven Projektphasen oft keine hohe Priorität geniesst, da sie unmittelbar keine geschäftlichen oder fachlichen Vorteile bringt. Zudem erfordert sie manchmal spezifische Kenntnisse, die nur bei wenigen, ohnehin sehr beschäftigten Personen vorhanden sind.
Entsprechend gilt es zu klären, wie die Dokumentation aussehen soll. Unterschiedliche Bedürfnisse können etwa durch die Aufgabenverteilung in einem Entwicklungsteam entstehen und einige Konsequenzen nach sich ziehen. Ein typisches Beispiel ist die Frage, wo eine Dokumentation ins Detail gehen soll und wo nicht. Während Details beim Verständnis helfen können, ändern sie sich erfahrungsgemäss öfter, was den Pflegeaufwand an gewissen Stellen erhöht. Durch häufige Änderungen an solchen Stellen kann es wiederum nötig sein, die Dokumentation ab und zu als Ganzes zu prüfen, damit sie konsistent bleibt. Dazu muss man klären, wie man die Dokumentation validiert, damit sie den Erwartungen entspricht.
Um die Erwartungen an eine Architekturdokumentation zu erfüllen, hilft es, sich an Best Practices zu orientieren. Ein Beispiel dafür sind Templates, die Inhalte und eine Struktur für Dokumentation vorgeben.
Zwei solche Templates sind arc42 (siehe Abbildung 1) und das SA4D-Template von Simon Brown. Beide sind ähnlich aufgebaut und versuchen, wesentliche Aspekte einer Architektur angemessen zu dokumentieren, um typische Bedürfnisse abzudecken. Bei Bedarf lassen sich beide Templates anpassen, sodass etwa Themen entfallen, die unwichtig sind.
Erste Dokumentation mit einem Canvas
Eine Alternative dazu ist ein Canvas. In den letzten Jahren sind mehrere Canvas-Formate für Softwarearchitektur wie der Architecture Communication Canvas (siehe Abbildung 2) aufgekommen. Ein Canvas bietet eine übersichtliche Struktur für die wichtigsten Aspekte einer Thematik. Da er diese Informationen auf einen Blick präsentiert, ist er zugänglich und visuell attraktiv.
Ein Canvas hilft, zügig eine erste Dokumentation zu erstellen. Wichtig ist aber zu prüfen, ob ein Canvas ausreicht, oder ob von Anfang an eine umfangreichere Dokumentation erforderlich ist. Später kann man einen Canvas durch weitere Dokumentation ergänzen, sollte dies notwendig sein.
Eine noch stärker fokussierte Form von Dokumentation, die Architecture Decision Records (ADRs), beschreibt Entscheidungen. Auch für sie gibt es unterschiedliche Vorlagen. Typischerweise legt ein ADR die Ausgangslage und den Sachverhalt dar, um den es bei einer Entscheidung geht, stellt Alternativen gegenüber und beschreibt die Variante, für die man sich entschieden hat. Hinzu kommen die sich daraus ergebenden Konsequenzen. ADRs eignen sich damit sehr gut, um eine Entscheidungsfindung zu begleiten und zu protokollieren.
Es gibt unterschiedliche Ansätze, wo und wie man ADRs verwaltet. Bei vielen Entwicklerinnen und Entwicklern ist es beliebt, sie mit dem Code zusammen als Markdown-Dokumente zu managen. Es sind aber auch andere Ansätze und Formate wie ein Wiki denkbar. ADRs fügen sich zudem gut in eine bestehende Dokumentation ein, die sich an einem der erwähnten Templates orientiert.
Die drei Ansätze stellen vernünftige Vorlagen für Architekturdokumentation dar. Während die umfangreichen Templates oder ein Canvas unterschiedliche Informationen zu einer Architektur bereitstellen, dokumentieren und begleiten ADRs die zugrundeliegenden Entscheidungen, die eine Architektur ausmachen. Deshalb sind ADRs gerade bei Entwicklerinnen und Entwicklern beliebt.
Keiner der Ansätze kann aber garantieren, dass eine Dokumentation den Erwartungen entspricht. Nicht nur können sich diese mit der Zeit ändern, es kann auch immer noch vorkommen, dass eine Dokumentation zu wenig gepflegt wird, etwa, weil die Zeit nicht reicht oder es vergessen wird.
Dokumentation automatisch erzeugen
Die bisher diskutierten Ansätze erfordern Arbeit und Zeit. Das wirft die Frage auf, ob Tools dabei helfen können, Aufwand zu sparen und Qualität und Aktualität sicherzustellen, insbesondere in Zeiten, in denen ein Team eine Software intensiv weiterentwickelt. In der Tat gibt es verschiedene Ansätze dafür.
Ein solcher Ansatz ist, durch AI-Tools wie Claude Code oder den GitHub CoPilot Dokumentation generieren oder prüfen zu lassen. AI-Tools wie ChatGPT oder Claude konnten bereits früher aus verschiedenen Artefakten wie Quellcode oder ADRs Architekturdokumentation generieren und iterativ aktualisieren. Während sie aber keinen direkten Zugriff auf die Artefakte eines Softwaresystems haben, gehen hier Coding Agents nochmal einen Schritt weiter, denn sie können etwa Komponenten- oder Laufzeitdiagramme in Notationen wie PlantUML oder Mermaid erstellen und dazu Code Repositories eigenständig analysieren.
Die so gewonnenen Resultate stellen eine gute Basis dar, von der aus an einer Dokumentation weitergearbeitet werden kann. Allerdings sollte man die Ergebnisse prüfen, da auch bei aktuellen AI-Tools das Risiko vorhanden ist, dass sie halluzinieren. Daher befreien einem auch diese KI-gestützten Ansätze aktuell nicht davon, an der Überarbeitung oder Validierung der Dokumentation aktiv mitzuwirken und sich dafür Zeit zu nehmen.
Es gibt aber auch Ansätze, um nach deterministischen Regeln Teile einer Dokumentation zu generieren. Für Entwicklerinnen und Entwickler ist das besonders interessant, da so unter anderem Sichten erzeugt werden können, die Aspekte wie die aktuelle statische Codestruktur zeigen und bei Bedarf mit anderen Teilen einer Dokumentation kombiniert werden können.
Ein solcher Ansatz ist Structurizr. Structurizr baut auf dem beliebten C4-Modell auf und verwaltet Architekturdokumentation als Workspaces, die im Wesentlichen aus einem Modell für die Softwarearchitektur sowie zugehörigen Sichten bestehen. Beschrieben wird ein Workspace über eine DSL (Domain-specific Language), wie das folgende Beispiel illustriert.
Listing 1: Einfacher Workspace, der den Structurizr-Client für .NET beschreibt
workspace {
model {
user = person "User"
softwareSystem = softwareSystem "Structurizr.NET" {
client = container "Structurizr.Client" {
user -> this
}
container "Structurizr.Core" {
client -> this
}
}
}
views {
systemContext softwareSystem {
include *
autolayout lr
}
container softwareSystem {
include *
autolayout lr
}
theme default
}
}
Das Modell beschreibt die Elemente, die die Architektur ausmachen, und deren Beziehungen sowie Verschachtelungen. So kann ein Softwaresystem beispielsweise aus mehreren Containern bestehen, die wiederum mehrere Komponenten enthalten. Basierend auf dem Modell definiert ein Workspace verschiedene, konsistente Sichten, wie eine Kontextsicht oder eine Komponentensicht, abhängig davon, wie detailliert oder ganzheitlich die Darstellung der Architekturelemente sein soll.
Es gibt Tools, um Structurizr-Sichten darzustellen und in unterschiedliche Formate zu exportieren. So kann man sie etwa in eine arc42-Dokumentation integrieren. Auch für die Pflege von Workspaces gibt es unterschiedliche Möglichkeiten und Tools, darunter Addons für verbreitete Editoren und IDEs wie IntelliJ IDEA oder Visual Studio Code. Die Structurizr-Website dokumentiert anschaulich mit Beispielen, wie man mit der DSL Workspaces erstellt. Ein Beispiel ist in Listing 1 zu sehen. Abbildung 3 zeigt die zugehörige Containersicht.
Integration in die CI-Pipeline
Zusätzlich zur DSL existieren für verschiedene Programmiersprachen Bibliotheken, um einen Workspace programmatisch zu pflegen. Entwicklerinnen und Entwickler können so echte Softwareartefakte direkt in das Modell einfließen lassen, etwa in der Form statischer Projektinformationen wie Konfigurationen. Für Plattformen mit Reflection-Mechanismen wie Java oder .NET können sie zudem die Struktur der Software analysieren und Modellelemente wie Komponenten und deren Beziehungen daraus ableiten. So lässt sich eine Dokumentation automatisch mit der tatsächlichen Architektur abgleichen.
jQAssistant ist ein weiteres Werkzeug, das automatisch Dokumentation für ein Softwaresystem erzeugen kann. jQAssistant analysiert die Artefakte einer Software, etwa den Code oder die zugehörige Versionsverwaltung, und repräsentiert gefundene Sachverhalte und Zusammenhänge als Graph. Dieser Graph wird in einer Graphdatenbank gespeichert, über welche er auf vielfältige Weise abgefragt werden kann. So lassen sich sowohl Zwischenergebnisse für weitere Verarbeitungsschritte wie auch Dokumentationen, Reports und Visualisierungen generieren. Zudem ist jQAssistant über Plugins erweiterbar und stellt damit ein mächtiges und flexibles Werkzeug dar, um Softwareprojekte zu analysieren und geeignet zu präsentieren.
Ein Tool, welches ebenfalls Dokumentation zu einer bestehenden Codebasis erzeugen kann, sich aber spezifisch an das Spring- und Java-Ökosystem richtet, ist Spring Modulith. Spring Modulith ist darauf ausgelegt, dass eine Java-Applikation in Module sowie Submodule aufgeteilt wird, die sich nur auf bestimmte Weise referenzieren dürfen. Diese strukturellen Regeln kann Spring Modulith ausdrücken und in einer Codebasis automatisch überprüfen, und es lassen sich dazu unterschiedliche Typen von Darstellungen erzeugen, die man in eine bestehende Dokumentation integrieren kann.
Mit diesen Tools und Frameworks ist es möglich, automatisch Darstellungen zu erzeugen, die gerade für Entwicklungsteams relevante sind. Dass reduziert vor allem bei vielen Änderungen an einem System den Aufwand für eine aktuelle Architekturdokumentation. Manche dieser Tools erfordern einen initialen Aufwand, um das gewünschte Resultat zu erzielen, und auch danach kann es notwendig sein, hin und wieder zu prüfen, ob die Dokumentation noch den Erwartungen entspricht, oder ob Anpassungen notwendig sind.
Die Architektur testen
Die bisherigen Überlegungen beschreiben Ansätze, um Dokumentation an eine vorliegende Architektur anzupassen. Es gibt aber auch Situationen, in denen eine Architektur Vorgaben für ein System macht und die Implementierung zur Architektur und ihrer Dokumentation konsistent gehalten werden soll. Als Nebeneffekt bleibt so auch die Dokumentation aktuell. Generell möchte man regelmäßig prüfen, ob die Umsetzung eines Systems den Vorgaben entspricht. So entdeckt man Abweichungen früher, solange sie einfacher zu beheben sind. Zu seltener Abgleich birgt zudem das Risiko, einzelne Abweichungen zu übersehen.
Entwickelt man aber ein System intensiv weiter, kann dieser regelmäßige Abgleich einigen Aufwand erzeugen, für den man typischerweise zu wenig Zeit eingeplant hat. Daher macht es Sinn, die Einhaltung von Architekturvorgaben durch Tools zu unterstützen, die über Abweichungen informieren.
Eine Bibliothek, die Entwicklerinnen und Entwickler dabei unterstützt, ist ArchUnit. Sie analysiert statische Eigenschaften einer Java- oder .NET-Codebasis und prüft beispielsweise, ob Komponenten zirkuläre Abhängigkeiten aufweisen oder Klassen mit bestimmten Eigenschaften in entsprechenden Modulen liegen. Entwicklerinnen und Entwickler schreiben mit ArchUnit Tests, die als Teil einer Testsuite oder Buildpipeline ausgeführt werden. So lassen sich Verletzungen von Architekturvorgaben zeitnah beheben. Spring Modulith verwendet ebenfalls ArchUnit, um die Struktur einer Applikation zu prüfen. Für andere Programmiersprachen und Plattformen existieren ähnliche Bibliotheken, darunter Konsist für Kotlin, TSArch für JavaScript und TypeScript sowie PyTestArch für Python.
Im Hinblick auf Architekturdokumentation bietet ArchUnit die Möglichkeit, Dokumentation und Tests miteinander zu verknüpfen und damit konsistent zu halten. Entwicklungsteams können Vorgaben zu statischen Abhängigkeiten als PlantUML-Komponentendiagramm spezifizieren, das sie als Teil der Dokumentation pflegen. Die Komponenten im Diagramm entsprechen Modulen oder Packages im Code, und ArchUnit prüft, ob in der Codebasis Abhängigkeiten zwischen Packages auftreten, die nicht erlaubt sind. So ist sichergestellt, dass die Struktur des Codes und die zugehörige Dokumentation zueinander konsistent sind.
Auch jQAssistant erlaubt die Überprüfung von Vorgaben. Durch die Verknüpfung von Daten, die aus unterschiedlichen Artefakten gewonnen werden, lassen sich vielfältige Validierungsszenarien umsetzen, die Ergebnisse in der Form von Sichten und Reports aufbereiten und mit weiterer Architekturdokumentation verknüpfen. Auch auf diese Weise lässt sich die Dokumentation einer Architektur mit deren Überprüfung verknüpfen und Konsistenz und Aktualität sicherstellen.
Beide Testansätze lassen sich beispielsweise über eine CI-Pipeline automatisieren. Dadurch werden Vorgaben und Umsetzung regelmäßig verglichen und allfällige Anpassungen und zugehörige Diskussionen finden zeitnah statt. Das Ergebnis ist eine Codebasis, die den Vorgaben und damit der Dokumentation entspricht. Je nach Projektkontext kann es aber ungeeignet sein, regelmäßig Architekturvorgaben in einer CI-Pipeline zu erzwingen. Architekturtests können aber auch informell nebenherlaufen. Auf die Weise bekommen Entwicklerinnen und Entwickler trotzdem mit, wenn sich die Software so ändert, dass Vorgaben verletzt werden.