Architekturentscheidungen dokumentieren

Keine Zeit? Hier die Kurzversion in 30 Sekunden.
- Die wichtigste Frage bei fremdem Code ist selten „Wie?“, sondern „Warum wurde das so gebaut?“. Die Antwort steht fast nie irgendwo.
- Architecture Decision Records (Michael Nygard, 2011) halten genau eine Entscheidung pro Datei fest: Titel, Status, Kontext, Entscheidung, Konsequenzen.
- Sie liegen als Markdown im Repository, sind kurz, werden nicht umgeschrieben, sondern bei Änderung durch einen neuen Eintrag ersetzt.
- Große Architekturdokumente (etwa nach arc42) beschreiben den Zustand, ADRs den Weg dorthin. Beides ergänzt sich.
- Der Aufwand ist klein, die Disziplin ist das Problem. Es lohnt sich bei Entscheidungen, die teuer zu ändern sind.
Es gibt einen Moment, den ich in vielen Projekten erlebt habe. Jemand liest eine Stelle im Code oder eine Konfiguration und sagt: „Das ist merkwürdig. Warum macht man das so?“ Und niemand im Raum weiß es. Die Person, die es entschieden hat, ist längst woanders, oder sie ist noch da und erinnert sich nur noch dunkel. Dann beginnen zwei Wege, beide unerquicklich. Entweder wird die Stelle nicht angefasst, weil sie ja irgendeinen Grund haben wird, oder sie wird „aufgeräumt“, und drei Wochen später stellt sich heraus, dass der Grund tatsächlich existierte.
Beides kostet. Das Wissen über das Warum ist der Teil, der am schnellsten verloren geht, und es ist der Teil, den kein Quelltext von selbst verrät.
Wo das Wissen bleibt
Das Wie lässt sich dem Code entnehmen, notfalls mit Mühe. Auch das Was steht meist irgendwo, in Tests, in der Doku, im Datenmodell. Das Warum dagegen besteht aus Abwägungen: Welche Alternativen gab es? Was wussten wir damals? Welche Einschränkung haben wir bewusst hingenommen? Diese Dinge wohnen in Köpfen, in Chatverläufen, in Mails, in Besprechungsnotizen, die keiner wiederfindet.
Eine Weile habe ich geglaubt, ein ordentliches Architekturdokument sei die Lösung. Man beschreibt Bausteine, Schnittstellen, Laufzeitsichten, und am Ende gibt es einen Abschnitt „Entscheidungen“. Solche Dokumente haben ihren Wert, und Vorlagen wie arc42 geben eine brauchbare Gliederung, sodass man nicht bei null anfängt. Aber ich habe auch gesehen, wie sie altern. Sie sind groß, also scheut man sich, sie zu ändern, und irgendwann beschreiben sie ein System, das es so nicht mehr gibt. Die Entscheidungen darin gehen im Fließtext unter.
Ein kleiner Gegenentwurf
Michael Nygard hat 2011 in einem Blogbeitrag einen anderen Ansatz vorgeschlagen, den er Architecture Decision Records nennt, kurz ADR. Die Idee ist bescheiden: Jede architekturrelevante Entscheidung bekommt ein eigenes, kurzes Dokument, und zwar eines, das man in zwei Minuten lesen kann. Er empfiehlt wenige feste Abschnitte:
- Titel: nummeriert, kurz, im Kern ein Satz („Nachrichten über eine Warteschlange verschicken“).
- Status: vorgeschlagen, akzeptiert, abgelöst oder verworfen.
- Kontext: Was war die Lage, welche Kräfte wirkten? Hier steht ausdrücklich auch Unschönes, etwa Zeitdruck oder fehlendes Wissen.
- Entscheidung: Was wird getan, in der Wir-Form und im Aktiv.
- Konsequenzen: Was folgt daraus, die guten wie die schlechten Seiten.
Die Dateien liegen als Markdown im Repository, direkt neben dem Code, etwa unter doc/arch/. Dort werden sie mit dem Code versioniert, tauchen im Review auf und müssen nicht in einem Wiki gepflegt werden, das irgendwann eine eigene Existenz führt.
Ein Beispiel
So könnte so ein Eintrag aussehen:
# 7. Bestellungen asynchron an das Lager melden
Status: akzeptiert (ersetzt 4)
## Kontext
Das Lagersystem ist nachts für Wartung nicht erreichbar und antwortet
tagsüber manchmal erst nach mehreren Sekunden. Bisher ruft der Shop es
synchron beim Abschluss der Bestellung auf; Kunden sehen deshalb
gelegentlich Fehlerseiten, obwohl die Bestellung gültig ist.
## Entscheidung
Wir speichern die Bestellung zuerst lokal und schicken die Meldung an
das Lager über eine Warteschlange. Ein separater Verbraucher liefert
sie aus und versucht es bei Fehlern erneut.
## Konsequenzen
+ Der Abschluss einer Bestellung hängt nicht mehr von der Erreichbarkeit
des Lagers ab.
- Das Lager erfährt von Bestellungen mit Verzögerung; die Anzeige des
Bestands ist nicht mehr exakt.
- Wir betreiben zusätzlich einen Message-Broker und müssen doppelte
Zustellung beim Verbraucher tolerieren.Der Hinweis „ersetzt 4“ ist Absicht: Vorher stand an dieser Stelle die Entscheidung für den direkten Aufruf, und beide Einträge bleiben nebeneinander lesbar. Wer in einem Jahr fragt, warum es eine Warteschlange gibt, findet die Lage und die Alternativen sofort, ohne jemanden suchen zu müssen, der dabei war. Das sind keine zwanzig Zeilen, und es beantwortet in einem halben Absatz, was später stundenlang Raten ersetzen würde. Interessant finde ich vor allem den Konsequenzen-Teil. Er zwingt dazu, die Nachteile hinzuschreiben, und das ist ehrlicher als jede Folie, auf der eine Entscheidung nur Vorteile hat.
Unveränderlich und ersetzt
Eine Regel macht das Ganze erst brauchbar: Ein ADR wird nicht nachträglich umgeschrieben. Hat sich die Lage geändert und fällt eine neue Entscheidung, entsteht ein neuer Eintrag, und der alte bekommt den Status „abgelöst“ mit einem Verweis auf den Nachfolger. Dadurch bleibt eine Geschichte erhalten. Man sieht, was man früher für richtig hielt, und warum man es später anders sah. Ohne diese Spur wirkt jede frühere Entscheidung hinterher wie ein Fehler, weil man sie mit dem heutigen Wissen beurteilt.
Dasselbe gilt für Irrtümer. Eine Entscheidung, die sich als falsch herausgestellt hat, ist kein Grund, den Eintrag zu löschen. Sie ist genau der Fall, aus dem man lernt.
Disziplin, Autorenschaft und die Frage nach dem Nutzen
Die Technik ist trivial, die Gewohnheit nicht. Ein paar Punkte, an denen ich es in der Praxis scheitern oder gelingen sehe:
Wer schreibt? Am besten die Person, die die Entscheidung vorantreibt, denn sie kennt den Kontext. Der Entwurf kann als Pull-Request laufen, sodass die Diskussion über die Entscheidung am Text stattfindet und nicht verloren geht. Der Review ist dabei fast wichtiger als das Ergebnis, weil im Schreiben oft erst auffällt, dass die Begründung dünn ist.
Wann? Kurz nach der Entscheidung, solange der Kontext frisch ist. Ein ADR, das Monate später aus der Erinnerung rekonstruiert wird, ist besser als keins, aber schlechter als eins, das noch am selben Tag entstand.
Wofür nicht? Nicht jede Kleinigkeit verdient einen Eintrag. Ob eine Methode in diese oder jene Klasse gehört, entscheidet das Code-Review. Ich würde ADRs für Entscheidungen reservieren, die teuer rückgängig zu machen sind oder die das Verhalten des ganzen Systems prägen: Wahl der Datenbank, Art der Kommunikation zwischen Teilen, Umgang mit Sitzungen und Authentifizierung, ein Framework, an das sich der Code stark bindet. Faustregel: Wenn ein neuer Entwickler in einem Jahr fragen könnte „Warum nicht einfach …?“, lohnt sich der Eintrag.
Ein Risiko bleibt. ADRs können zur Pflichtübung werden, die man abhakt, ohne nachzudenken, oder sie verschwinden nach der dritten Woche still. Gegen Ersteres hilft der Konsequenzen-Abschnitt, gegen Letzteres nur, dass das Team es wirklich will. Ich würde klein anfangen, mit der nächsten größeren Entscheidung, nicht mit einer Nachdokumentation der gesamten Vergangenheit. Ein sinnvoller Nebeneffekt: Wer bei einer Entscheidung merkt, dass ihm der Kontext-Absatz schwerfällt, hat meist noch nicht verstanden, worum es eigentlich geht. Dann ist es besser, noch einmal zu reden, als etwas Unausgegorenes festzuschreiben.
Wer ein Architekturdokument hat, muss darauf nicht verzichten. Das Dokument beschreibt, wie das System heute aussieht, die ADRs erzählen, wie es dazu kam. Beides zusammen hat mir bisher mehr geholfen als jedes für sich.
Beitragsbild: eigene Collage mit Logos von Wikimedia Commons (Markdown-Logo: Dustin Curtis, CC0 1.0); die Marken gehören ihren Inhabern.
Christian Ackermann
Softwareentwickler (C++, C, Java, C#) aus der Oberpfalz, bloggt seit 2001 über Linux, Technik und Kochen.