Gut dokumentiert: Architecture Decision Records
Der Einsatz von ADR ist eine Methode, Entscheidungen im Entwicklungsprozess nachvollziehbar und kontinuierlich zu dokumentieren.
- Oliver Fischer
Architekturdokumentation soll anderen Menschen beim Verständnis der entwickelten Software helfen. Welche Methode und wie viel Aufwand für die Dokumentation richtig ist, müssen Teams individuell entscheiden. Ein schlanker Ansatz, der sich leicht in die tägliche Arbeit integrieren lässt, sind Architecture Decision Records (ADR).
Fast jeder kennt Momente, bei denen sich Fragen nach dem Warum stellen: Warum hat jemand etwas auf die eine Weise und nicht anders erledigt? Warum hat ein Team eine bestimmte Technik gewählt? Warum hat niemand die Konsequenzen gesehen, die daraus entstehen konnten? Auslöser für die Fragen können einzelne, kurze Methoden oder die Gesamtarchitektur sein. Dahinter steht wiederum die Frage, ob das Team die Entscheidung sorgfältig getroffen und überdacht hat.
Letzteres ist wahrscheinlich, aber häufig lässt sich für andere nicht nachvollziehen, welcher Gedanke zu der vorliegenden Entscheidung geführt hat und welches Ziel dahintersteht. Die Anwender kennen nur das Ergebnis und die Auswirkungen, aber nicht den Weg, der zu der Entscheidung geführt hat.
Keine falschen Entscheidungen
Wer eine Entscheidung trifft, verfolgt üblicherweise ein Ziel. Dabei gilt es, zahlreiche Aspekte zu berücksichtigen und viele Informationen in die Entscheidungsfindung einzubeziehen. Menschen müssen seit Urzeiten ständig Entscheidungen treffen und können das üblicherweise gut, wenn sie mit der gleichen oder einer ähnlichen Situation vertraut sind.
Sie können auf Erfahrung zurückgreifen, wenn sie die Ausgangssituation, das angestrebte Ziel und die sich daraus ergebenden Konsequenzen kennen. Je weniger über das zu lösende Problem, mögliche Lösungsansätze und deren Konsequenzen bekannt ist, desto schwieriger ist die Entscheidung.
Wissen und Unwissen
Zur Klassifikation von Wissen existieren zahlreiche Modelle. Eines davon setzt auf eine 2x2-Matrix aus "Known" und "Unkown". Demnach gibt es auf der einen Seite die Known Knowns, also Wissen, das jemand bewusst wahrnimmt. Auf der anderen Seit gibt es die Unknown Unknowns: Wissen, das jemand nicht nur nicht hat, sondern auch nicht weiß, dass es fehlt. Ergänzt wird die Matrix durch die Known-Unknowns und die Unkown-Knowns.
Ersteres stellt Wissen dar, über dessen Fehlen sich jemand bewusst ist und sich aneignen oder das Fehlen als Risiko einkalkulieren kann. Letzteres ist Wissen, dass zum Einsatz kommt, ohne dass sich derjenige darüber im Klaren ist, dass er es hat. Der Einteilung in diese Matrix hat der ehemalige US-amerikanische Verteidigungsminister Donald Rumsfeld auf einer Pressekonferenz 2002 im Vorfeld des Dritten Golfkrieges zu Bekanntheit verholfen.
Zu den objektiven kommen noch die subjektiven Einflussfaktoren, die mit der individuell handelnden Person zusammenhängen. Unter anderem sind Werte und Moral ein subjektiver Einflussfaktor. Menschen neigen dazu, ihre subjektiven Faktoren als objektiv darzustellen und wahrzunehmen. Demnach kann es keine objektiv richtigen Entscheidungen geben.
Damit ist jede Entscheidung aus Sicht desjenigen, der sie trifft, zunächst subjektiv richtig. Sie erfüllt ihren Zweck zu dem Zeitpunkt und für die Person in der Situation mit dem Wissen sowie der jeweiligen Erfahrung.
Das mag beschönigend klingen, hilft aber dabei, die Situation nüchterner zu betrachten. Per se gibt es somit keine falschen Entscheidungen. Zum Zeitpunkt der Entscheidung lässt sich oft nicht abschätzen, welche Folgen sie haben wird. Und es ist nicht auszuschließen, dass eine vielleicht anfangs als falsch beurteilte Entscheidung sich später als die bessere Entscheidung in Hinblick auf die Konsequenzen erweist.
Nachvollziehbare Architektur
Entscheidungen festzuhalten, sie zu dokumentieren ist ein wichtiger Bestandteil der Arbeit an einer Softwarearchitektur. Nur auf die Weise können andere später die Entwicklung eines Systems und die Leitgedanken nachvollziehen. Bei weiteren Entscheidungen lässt sich qualifiziert überlegen, ob das Team die Entscheidungen beibehalten oder etwas ändern soll. Diskussionen, ob beispielsweise ein Framework X das Framework Y ersetzen soll, lassen sich anders führen, wenn die Beteiligten sich auf vorherige Entscheidungen beziehen können, zu denen die jeweiligen Entscheider Stellung beziehen müssen.
Zu einer gut dokumentierten Entscheidung gehört die Situation, in der sie getroffen wurde, aber auch die verfolgten Ziele. Das gilt unabhängig davon, ob Teams für Softwareprojekte anfangs viel Zeit in das Erarbeiten einer Softwarearchitektur investiert haben oder die Softwarearchitektur im Lauf des Projekts erstellen. Bei beiden Ansätzen stehen immer wieder Entscheidungen an. Grundsätzlich gilt: Je länger ein Projekt läuft, desto mehr Entscheidungen sind im Lauf der Zeit im Vergleich zum Start gefallen. Dokumentationen, die nur zu Beginn entstehen, sind daher veraltet und teilweise nutzlos, da sie nicht dem aktuellen System entsprechen und mehr Verwirrung stiften als Nutzen schaffen.
Teams müssen beziehungsweise können nicht jede Entscheidung dokumentieren. Auf die Frage, welche es zu dokumentieren gilt, gibt es keine pauschale Antwort. Ob für ein Java-System Apache Commons oder Google Guava zum Einsatz kommt, muss nur dann in die Dokumentation einfließen, wenn es eine explizite Entscheidung gegen eine der beiden Bibliotheken gibt. Ebenso müssen Teams nicht unbedingt dokumentieren, ob sie anfangs PostgreSQL oder MariaDB einsetzen, eine Migration von einer der beiden zu Cassandra hingegen durchaus.
Gute Anzeichen für die Notwendigkeit der Dokumentation ist, wenn eine Entscheidung von bestehenden Best Practices oder eigenen Standards abweicht oder ihr lange Diskussionen vorausgegangen sind.
Angstfrei dokumentieren
In der idealen Welt ist jede Entscheidung durch das Abwägen der bekannten Fakten, des verfügbaren Wissens und der Werte bestimmt. In der Praxis fallen jedoch selten einheitlich als optimal betrachtet Entscheidungen, sondern oft sind Kompromisse das Beste, was erreichbar ist. Äußere Rahmenbedingungen wie Zeit, Geld oder Konflikte im Team haben ebenfalls Einfluss auf Entscheidungen.
Derartige Gründe offen anzusprechen und beispielsweise einzuräumen, dass eine Idee zu wenig Unterstützung gefunden hat, erfordert Mut. Dennoch ist es wichtig, solche Fakten festzuhalten.
Die ADR-Methode
Eine Art der Dokumentation sind Architecture Decision Records (ADR). Sie gehen auf eine Idee von Michael Nygard aus dem Jahr 2011 zurück. Neu war dabei nicht die Idee, Entscheidungen festzuhalten, sondern die praktische Umsetzung. Zum einen liegt der Fokus auf der Entscheidung und nicht auf dem Weg dorthin. Damit unterscheiden sich Architecture Decision Records von anderen Methoden, die versuchen, die Entscheidungsfindung zu dokumentieren, indem sie beispielsweise die einzelnen Lösungsmöglichkeiten vergleichen.
Aus der Erfahrung, dass kurze Dokumente sich leichter schreiben und lesen lassen als lange, sollte für jede Entscheidung ein eigenes Dokument als Architektur Decision Record entstehen. Das Vereinfachen hilft bei der späteren Pflege.
Der konkrete Dateiname bildet sich aus dem gewählten Namen der Architekturentscheidung, gefolgt von einer eindeutigen und fortlaufenden Nummer (ID).
Jeder Datensatz setzt sich aus den folgenden Abschnitten zusammen:
- Titel (title): kurze, den Inhalt des ADR wiedergebende Beschreibung der Entscheidung.
- Kontext (context): Beschreibung der Bedingungen, die zu der Entscheidung geführt haben.
- Entscheidung (decision): Beschreibung der Entscheidung, die im Rahmen des vorher beschriebenen Kontexts erfolgt ist.
- Status (status): Position im Lebenszyklus der Entscheidung wie "proposed", "accepted", "discarded", "deprecated" oder "superseeded".
- Konsequenzen (consequences): Auflistung aller positiven und negativen Konsequenzen.
Die Beschreibung des Kontexts erfolgt ohne sprachliche Wertung, um den Lesern einen neutralen Einstieg beim Verstehen der Entscheidung zu ermöglichen. Sie sollte das zu erreichende Ziel, die technischen und andere Randbedingungen festhalten.
Eine ungewöhnlich lange Beschreibung kann ein Zeichen dafür sein, dass entweder zu viele und damit für die Nachvollziehbarkeit unnötige Details enthalten sind, oder dass es sich um mehr als eine Entscheidung handelt. In letzterem Fall ist es sinnvoll, den ADR auf mehrere aufzuteilen.
Der Architecture Decision Record für den Einsatz von Ruby als Skriptsprache könnte beispielsweise in der Datei ruby-als-skriptsprache-0001.md mit dem folgenden Inhalt festgehalten worden sein.
= ADR 0002: Ruby als Skriptsprache zum Repository Management
== Kontext
Die Git-Repositorys unseres Produkts werden auf GitHub Enterprise
bei uns im Unternehmen gehostet. GitHub wird dabei f�r die
Verwaltung von Issues und das Release Management verwendet.
In unserer t�glichen Arbeit f�hrt es immer wieder zu Problemen,
dass es in den Projekten unterschiedliche Labels f�r die Issues
gibt und nicht �berall die gleichen Milestones verf�gbar sind.
Das erschwert die Arbeit und Planung. Versuche Labels und
Milestones manuell aktuell zu halten, sind immer
wieder gescheitert.
== Entscheidung
Wir wollen die Pflege unserer Git-Repositorys in GitHub Enterprise
und deren Metadaten �ber Skripte automatisieren, um deren
einheitliche Konfiguration sicherzustellen und Fehler in der
Konfiguration zu finden. Durch den Einsatz von Skripten
kann die Pflege auch �ber unseren CI-Server automatisiert
werden, und alle Teammitglieder k�nnen die Arbeit �bernehmen.
Dabei haben wir uns f�r Ruby als Skriptsprache entschieden. Zum
einen weil GitHub mit Octokat eine Ruby-Library bereitstellt und
zum anderen weil Ruby im Team gegen�ber der Kombination
von JavaScript und Nodes.js die gr��ere Akzeptanz hat.
== Status
Accepted
== Konsequenzen
Aufgrund dieser Entscheidung muss im Team grundlegendes Ruby-
Wissen aufgebaut werden und zum Teil existierende Python- und
Bash-Skripte ersetzt werden. Weiterhin m�ssen wir uns auf die zu
nutzenden Labels f�r Issues einigen und anschlie�end alte Labels
durch neue ersetzen.
---
Der beispielhafte Architecture Decision Record zeigt auf den zweiten Blick auf, wie schwer das Abgrenzen von Entscheidungen ist. Genau genommen enthält er zwei einzelne Entscheidungen: Die erste ist der Einsatz von Skripten für das Repository-Management und die zweite die Wahl von Ruby als Skriptsprache. Wie scharf die Trennung erfolgen soll, müssen Teams im Einzelfall entscheiden. Dabei gilt es, die passende Balance zwischen Aufwand und Nutzen zu finden.
Blick in die Werkzeugkiste
Inzwischen existieren einige Tools rund um Architecture Decision Records, wie ein Blick auf die Site der ADR-GitHub-Organisation zeigt. Nat Pryce hat eine Sammlung von ADR-Tools als Bash-Skript-Sammlung geschrieben, die sich direkt auf den Vorschlag von Michael Nygard beziehen. Sie lässt sich unter anderem als Tarball herunterladen. Nach dem Entpacken und Einbinden des Verzeichnisses in den Pfad lässt sich folgendermaßen der erste ADR erzeugen:
> adr init
Der Befehl initialisiert das Verzeichnis, in dem das Tool die ADRs ablegt. init erzeugt dabei den ersten ADR, der die Entscheidung dokumentiert, Architekturentscheidungen mit ADR zu dokumentieren.
Weitere ADRs lassen sich beispielsweise wie folgt anlegen:
> adr new Ruby als Skriptsprache zum Repository Management
Die ADR-Tools legen daraufhin die Grundstruktur als Vorlage an, die Teams mit der eigentlichen Entscheidung füllen müssen.
Das Anlegen von Textdateien und das Hochzählen einer laufenden Nummer sind freilich kein Hexenwerk, aber die ADR-Tools bieten zahlreiche Annehmlichkeiten. Unter anderem aktualisieren sie beim Anlegen eines neuen ADR Einträge, die damit ungültig werden. Wenn die Entscheidung für Ruby die ADR-Nummer 2 hat und im Beispielszenario später die Automatisiserung des Repository Managements stattdessen mit Node.js erfolgen soll, lässt sich folgender Befehl verwenden:
> adr new -s 2 NodeJS als Skriptsprache zum \
Repository Management
Die ADR-Tools setzen dabei den Status des ADR 2 auf "superseeded" und verlinken den neuen und den alten ADR miteinander.
Deutlich wichtiger als das Tooling zur Verwaltung von ADRs ist das Format, in dem die Einträge geschrieben sind. Das kann eine einfache Textdatei sein, aber ebenso gut lassen sich ADRs über ein Wiki verwalten. Die auf der Seite der ADR-GitHub-Organisation aufgeführten Tools verwenden hauptsächlich Asciidoctor und Markdown als Markup Language. Versionsverwaltungssyteme wie GitLab oder GitHub zeigen beide Formate an, sodass Entwickler ADRs über eine Weboberfläche ohne zusätzliche Werkzeuge lesen können.
Gut dokumentiert
Dokumentation ist nur gut, wenn sie das richtige Wissen vermittelt. Architecture Decision Records sollen helfen, getroffene Entscheidungen zu kommunizieren und nachvollziehbar niederzuschreiben. Dazu gehört immer, dass mit der Entscheidung zu erreichende Ziel zu benennen.
Ob ein ADR das schafft, lässt sich daran überprüfen, ob er Antwort auf die fünf "W"-Fragen gibt: Wann? Wer? Warum? Wozu? Was? Lassen sich die Fragen schlüssig aus dem ADR heraus beantworten, besteht eine gute Chance, dass er seinen Zweck erfüllt. Optimalerweise beantwortet ein unbeteiligter Reviewer, der nicht an der Entscheidung mitgewirkt hat, die Fragen aus dem ADR heraus.
Dokumentation ist kein Selbstzweck. Daher gibt es in der Praxis gute Gründe, sich bewusst dagegen zu entscheiden. Wenn nicht alle Beteiligten den Willen zur Dokumentation teilen, ist es wenig effizient, sofern nur Einzelne sich des Themas annehmen. Gegen eine Dokumentation spricht auch, wenn Teams nur die unkritischen Entscheidungen dokumentieren können, denen jeder zustimmt, es aber nicht schafft, für die wichtigen Themen gemeinsam getragene Entscheidungen zu treffen.
Konsequente Umsetzung
Architecture Decision Records stellen eine einfache Methode dar, schnell und ohne viel Aufwand Architekturentscheidungen zu dokumentieren. Konsequent angewendet können sie helfen, bestehende Architekturen besser zu verstehen und spätere Entscheidungen über Umbauten oder Erweiterungen fundierter zu treffen und so Änderungen zu vermeiden, die blind gegenüber bewußt getroffenen Entscheidungen sind.
Wichtiger als das konkrete Format ist jedoch, dass Teams Entscheidungen nachvollziehbar festhalten und konsequent mit der Dokumentation arbeiten und sie auf dem aktuellen Stand halten.
Oliver Fischer
hilft als Freelancer Firmen, ihre Ziele zu erreichen und Ideen zu verwirklichen. Nebenbei arbeitet er an jQAssistant mit und organisiert die JUG Berlin-Brandenburg.
(rme)