Warum man ADRs schreiben sollte
(github.blog)ADR = Architecture Decision Records
Festzuhalten, warum architektonische Entscheidungen so getroffen wurden, direkt in der Codebasis.
GitHub setzt das bereits in den mobilen iOS-/Android-Teams ein und erklärt in diesem Beitrag, warum das nötig ist.
Nicht für dich, sondern für dein zukünftiges Ich
Ein ADR ist kein Rückblick auf eine von mir getroffene Entscheidung, sondern hilft dabei, sich 6–12 Monate später an das Mindset zu erinnern, das bei der Entscheidung für diese Architektur ausschlaggebend war.
Ein ADR hält den Zeitpunkt fest, an dem eine Entscheidung getroffen wird, und umfasst alles bis hin zu PoCs, die in Meetings, Zoom-Calls, Slack oder im Code behandelt wurden.
Es geht darum, den Kontext aus dem Kopf in Worte zu fassen, damit man ihn später, wenn man sich diese Architektur erneut ansieht, wieder im Kopf rekonstruieren kann.
Der eigentliche Bonus zeigt sich, wenn dich Monate später jemand vorwurfsvoll fragt, warum das Modul GitHubAPIClient so funktioniert.
Statt 30 Minuten Pairing zu investieren, um den Code zu erklären, kannst du einfach dieses ADR weitergeben und damit die Entscheidungen erläutern, die beim Bau des Moduls getroffen wurden.
Nicht für dich, sondern für deine Kolleg:innen
Ein ADR sollte mehr enthalten als nur eine Ein-Zeilen-Erklärung wie „Diese Funktion ist die Implementierung von Feature-#3128“.
Es ist ein ausführlicheres Format, das Kolleg:innen hilft zu verstehen, warum diese Funktion auf genau diese Weise und nicht anders gebaut wurde.
(Zum Beispiel ausgedrückt durch „in Betracht gezogene Alternativen“, „Vor- und Nachteile“ usw. im ADR.)
Was für dich einfach ist, kann für Kolleg:innen komplex sein.
Wenn du dir etwas Zeit nimmst und den Denkprozess hinter einer Entscheidung festhältst, gibst du dem Team die Möglichkeit, in deinen Kopf hineinzuschauen.
Durch das Schreiben von ADRs wird „Decision Socialization“ möglich.
So trifft nicht mehr eine Einzelperson Entscheidungen im Alleingang, sondern das Team trifft Entscheidungen, für deren Wartung es gemeinsam Verantwortung übernimmt.
Wenn du ein ADR schreibst, bevor du den Pull Request einreichst, kannst du vom Team, das es prüft, bessere PR-Reviews bekommen.
Nicht für dich, sondern für zukünftige Kolleg:innen
Ein ADR ist nicht dazu da, zu zeigen, wie klug du bist, oder Menschen ratlos auf die von dir entworfene Architektur blicken zu lassen.
Ein ADR hilft neuen Teammitgliedern dabei zu verstehen, wie die aktuelle Codebasis aussieht und wie sie sich im Lauf der Zeit entwickelt hat.
Wenn ein Team skaliert und wächst, nehmen die Kommunikationswege zwischen den Teammitgliedern zu.
Solche dokumentierten Entscheidungen helfen dabei, auch mit neu dazukommenden Personen zu kommunizieren, wenn das Team wächst.
Das beste Szenario ist, dass ein Teammitglied ein neues ADR schreibt, das eine Entscheidung ersetzt, die du früher getroffen hast, und du in Zukunft von deinen Kolleg:innen lernen kannst.
„Schreibt mehr ADRs. Jedes Mal, wenn unser Team wächst und die Codebasis komplexer wird, sind ADRs eine gute Möglichkeit, unserem zukünftigen Ich, unseren aktuellen Teammitgliedern und zukünftigen Teammitgliedern zu helfen.“
3 Kommentare
Unter den E-Government-Beispielen gibt es auch das bekannte Gov.UK, das ein Repository mit den eigenen ADRs zur AWS-Cloud-Architektur pflegt.
https://github.com/alphagov/govuk-aws/…
Das war eine gute Referenz.
ADR-Beispiele
Entscheidung für ein CSS-Framework
https://github.com/joelparkerhenderson/architecture_decision_record/…
Annahme: Da wir eine moderne, schnelle und responsive Web-App bauen wollen, möchten wir kein jQuery verwenden
Einschränkung: Ein Framework, das ohne jQuery genutzt werden kann
Abgewogen: Nichts verwenden oder zwischen Bootstrap/Bulma/Foundation/Materialize/Semantic UI wählen; insbesondere Bulma und Semantic UI wurden intensiv geprüft
Monorepo vs. Multirepo
https://github.com/joelparkerhenderson/architecture_decision_record/…
→ Als SCM wird git verwendet, daher muss zwischen monorepo vs. polyrepo vs. hybrid entschieden werden
→ Wenn Organisation/Team/Projekt klein ist und schnelle Iteration wichtig ist: Monorepo
→ Wenn Organisation/Team/Projekt groß ist und Stabilität wichtig ist: Polyrepo
Entscheidung für Programmiersprachen
https://github.com/joelparkerhenderson/architecture_decision_record/…
→ Für das Frontend TypeScript
→ Für das Backend Rust
→ Das Frontend soll zwar allgemein einsetzbar sein, aber schnell entwickelt, ausgerollt und iteriert werden können. Legacy-Kompatibilität ist nicht erforderlich
→ Das Backend hat höhere Anforderungen als das Übliche. Qualität, Stabilität und Sicherheit sind wichtig. Nahezu Echtzeit-Niveau ist erforderlich (es darf keine Stopps durch GC geben). Funktionale Programmierung / parallele Verarbeitung und Multicore-Processing sowie Speichersicherheit sind ebenfalls wichtig
Einschränkung: Es muss unbedingt in der Serverless-Umgebung großer Cloud-Services (Amazon Lamba) ausführbar sein
Abgewogen: C/C++/Clojure/Elixir/Erlang/Elm/Flow/Go/Haskell/Java/Javascript/Kotlin/Python/Ruby/Rust/TypeScript
Diskussion:
→ C: Wegen geringer Sicherheit ausgeschlossen; Rust kann die meisten Dinge besser
→ C++: Wegen Unübersichtlichkeit ausgeschlossen; Rust kann die meisten Dinge besser
→ Clojure: Hervorragende Modellierung; Lisp am ähnlichsten; exzellente Runtime auf der JVM
→ Elixir: Hervorragende Runtime für Deployment und Concurrency; ausgezeichnete Developer Experience; relativ kleines Ökosystem
→ Erlang: Hervorragende Runtime für Deployment und Concurrency; etwas anspruchsvolle Developer Experience; relativ kleines Ökosystem
→ Elm: Vielversprechend; IBM teilt gute Praxisbeispiele; kleines Ökosystem
→ Flow: Interessante Verbesserung für JS; aber Entwickler wenden sich zunehmend davon ab
→ Go: Hervorragende Developer Experience; hervorragende Concurrency; es gab schlechte Entscheidungen, die die Sprache seltsam machen
→ Haskell: Beste funktionale Sprache; kleine Entwickler-Community; nicht viele erfolgreiche Beispiele in Produktion
→ Java: Beste Runtime; hervorragendes Ökosystem; nur mittelmäßige Developer Experience
→ JavaScript: Die populärste Sprache; das breiteste Ökosystem
→ Kotlin: Verbessert vieles an Java; starke Unterstützung durch JetBrains; verschiedene erfolgreiche Beispiele für den Wechsel von Java zu Kotlin
→ Python: Die populärste Sprache im Bereich Systemadministration; gute Analyse-Tools; gute Web-Frameworks; wurde aufgegeben, nachdem Google sich für Go entschieden hatte
→ Ruby: Beste Developer Experience; bestes Web-Framework; großartige Community; extrem langsam; schwer zu paketieren
→ Rust: Beste neue Sprache; betont Zero-cost abstractions; betont Concurrency; relativ kleines Ökosystem; bei einigen Compiler-Optimierungen gibt es Grenzen (z. B. muss direkter Speicherzugriff
unsafesein)→ TypeScript: Fügt JavaScript Typen hinzu; hervorragender Transpiler; Entwickler wechseln zunehmend von JS zu TS; starke Unterstützung durch Microsoft
Es wurde beschlossen, VM-basierte Optionen nicht auszuwählen (da sie die Komplexität erhöhen)
Für die schnellste Runtime würden JS und C gewählt
Für eine Runtime, die fast genauso schnell wie die beste ist, würden TypeScript und Rust gewählt
Falls VM und Web-Framework ausgewählt worden wären
→ Closer und Luminous
→ Java und Spring
→ Elixir und Phoenix