Dokumentation als Code

So kann Dokumentation stabil bleiben UND: 'Doc as Code' ist nicht gleich 'Code as Doc'
Dieter Baier
1.0
03/2023

Doc-as-Code bedeutet nicht, dass Code die Dokumentation ersetzt. Warum auch? Es müsste dann ja Code-as-Doc heißen.

Es bedeutet, Dokumentation mit denselben Prinzipien zu behandeln wie Software: strukturiert, versioniert, automatisiert und nahe am Code.

Dieser Artikel erklärt, warum klassische Dokumentation oft scheitert und wie ein Doc-as-Code-Ansatz helfen kann, sie dauerhaft aktuell und nutzbar zu halten.

Zwei Mythen über Dokumentation

Mein Code ist die Dokumentation

— Entwickler:Innen

Kennen Sie diese Aussage?

Ich kenne diese Aussage sehr gut und benutze sie gerne selbst. Sie funktioniert aber nur unter folgenden Voraussetzungen:

  • Der Code ist nach Clean Code Prinzipien geschrieben und man kann wirklich aufgrund der Einhaltung von klarer und eindeutiger Namensgebung von Funktionsnamen, Variablennamen, Schnittstellen etc., der Einhaltung des Single Responsible Principle und anderen best practices im Code selbst erkennen, worum und warum es bei dem Code geht

  • Das System ist wenig komplex, sodass es keine zusätzliche Architekturdokumentation geben muss (ist meist eine Falschannahme!)

  • Der Code ist für alle Stakeholder zugänglich und alle Stakeholder können den Code lesen

  • …​

Im Grunde ist diese Aussage einfach falsch, denn der Code kann maximal ein Teil der Dokumentation eines Software-Systems sein. Wenn er aber wirklich sauber geschrieben ist, kann er durchaus Bestandteil einer Dokumentation sein.

Will man ernsthaft und seriös Software bauen, kommt man um Dokumentation neben dem Code nicht umher.

Dokumentation ist veraltet, sobald sie geschrieben ist

— Entwickler:Innen

Ja, das stimmt - wenn es falsch gemacht wird.

Drei zentrale Fragen der Dokumentation

Erstens muss man sich fragen, WAS dokumentiert werden soll, zweitens, WIE und drittens, WARUM man dokumentieren will.

Je nach Umfeld kann es durchaus unterschiedliche Anforderungen an eine Dokumentation geben. Projekte im öffentlichen Dienst fordern oft umfangreiche Dokumentation, um die man einfach nicht herumkommt. Ganz einfach, weil es so ist. Systeme, bei denen u.U. sogar Menschenleben auf dem Spiel steht, werden sicherlich andere Dokumenationen erfordern, als eine Verwaltungssoftware.

Wie auch immer. Sobald man ein System bauen muss, dass aus mehreren Bausteinen besteht, wird man sich Gedanken über die Architektur machen und die gehört dokumentiert. Und wenn man es richtig macht, entsteht Architektur immer vor dem Code.

Natürlich entsteht die Architektur heut zutage und Gott sei Dank nicht upfront. Gute Architektur ist evolutionär und wächst mit den Anforderungen. Aber trotzdem steht vor dem Code immer ein Design und es gibt immer Gründe, warum man Code schreibt (fachliche Anforderungen, Qualitätsanforderungen, etc.). All das gehört dokumentiert.

D.h. aus Sicht eines Softwareentwicklers und / oder Softwarearchitekten wird das WAS mindestens mit einer Dokumentation der Architektur beantwortet werden. Wie diese Dokumentation aussehen soll, ist individuell und kann sich von Projekt zu Projekt unterscheiden. Aus Bequemlichkeit halte ich mich bei solchen Sachen an Bewährtes und von Fachleuten entwickelte Best practices. Daher halte ich mich in Sachen Architekturdokumentation an die arc42-Struktur. Aber darum geht es in diesem Artikel gar nicht.

Gehen wir dann mal an das WARUM soll ich etwas dokumentieren, wenn ohnehin der Code die eigentliche Wahrheit ist?

Meine erste Antwort wäre direkt: nicht jeder Stakeholder kann und will Code lesen. Projektleiter:Innen (wenn es welche gibt) oder aber auch ProductOwner:Innen haben vielleicht Zugriff auf den Code aber sie haben einen ganz anderen Blick auf die Software, für die sie Verantwortung tragen.

Die Dokumentation muss also auch abstraktere oder auch ganz andere Blickwinkel befriedigen. So wird in einer Architekturdokumentation eher auf das Warum sollte die Software so geschrieben werden, wie sie - hoffentlich - auch geschrieben wurde (das Sicherzustellen ist eine andere Disziplin innerhalb des Software-Entwicklungsprozesses). Sie wird also diverse Anforderungen dokumentieren und diese mit Strategien und Entscheidungen verknüpfen, welche letztendlich mit dem Code abgebildet werden sollten.

Aber WIE sollte nun dokumentiert werden, damit das Team die Dokumentation auch pflegt und aktuell hält?

Nun, meine Erfahrung sagt, dass es sowenig Mediumwechsel wie möglich geben sollte, damit auch die Entwickler:Innen - im Idealfall sogar gerne - dokumentieren. Heißt: Je näher am Code, desto besser.

Ich versuche daher, jegliche Dokumentation im ASCII-Format (wie es der Code auch ist) zu schreiben und so nahe am Code, wie möglich abzulegen. Wenn möglich und sinnvoll, sogar im gleichen Source-Repository.

Wenn ich erst gar nicht suchen muss, wo die Dokumentation abgelegt ist, sondern direkt mit meinem Code bekomme, habe ich alles an einem Platz und kann zwischen Dokumentieren und Codieren ohne Medienbruch leicht hin- und herwechseln.

Außerdem ist so eher sichergestellt, dass Code und Dokumentation nicht zu sehr auseinander läuft. Der Entwicklungsprozess kann dies auch leichter sicherstellen, da er sich nur mit einem Medium beschäftigen muss.

Ist das nun schon Doc-as-Code?

NEIN.

Was bedeutet Doc-as-Code wirklich?

Ablageort der Dokumentation oder Medium ist nicht entscheidend für Doc-as-Code. Wenngleich es sicherlich Medien gibt, die sich besser eignen, wirklich Doc-as-Code zu leben, als es andere Medien tun.

Aber ich kann Doc-as-Code in einem Git-Repository genauso leben, wie in Confluence oder ähnliche Plattformen.

Doc-as-Code bedeutet für mich, dass ich nicht nur Text schreibe und Bilder einfüge, sondern, dass ich die Dokumentation genauso pflege, wie ich meinen Code Pflege.

D.h., ich versuche auf eine erkennbare Struktur zu achten. Ich versuche auch in der Dokumentation das Single Responsible Principle einzuhalten. Und ich versuche Duplizierungen zu vermeiden und nichts zu schreiben, was nicht gebraucht wird (YAGNI).

Ein sehr wichtiger Aspekt hilft mir darüber hinaus auch bei der Entscheidung, welches Medium ich verwende (leider ist das in vielen Kundenprojekten nicht möglich, wenngleich ich schon versuche, darauf einzuwirken): Write once, deliver anywhere. Das wird aus meiner Sicht im Kontext von Dokumentation oft unterschätzt, ist aber spätestens dann absolut wichtig, wenn ich meine Dokumentation ausliefern muss oder unterschiedlichen Stakeholdern aus unterschiedlichen Abteilungen, vielleicht sogar Firmen zugänglich machen sollte.

Es muss also möglich sein, dass ich meine Dokumentation einmal schreibe, sie aber z.B. als Website präsentieren oder auch als PDF verschicken kann. Und dabei soll die Qualität nicht wirklich unterschiedlich sein (die Druckfunktion des Browsers wird i.d.R. kein zufriedenstellendes Ergebnis liefern).

Dann kommen aber auch noch die unterschiedlichen Sichten hinzu. Ich muss also meine Dokumentation so aufbereiten können, dass sie je nach Anforderung auch mal Dinge weglässt. Z.b. will man vielleicht keine Abteilungsnamen in dem PDF, das man an den externen Dienstleister schickt, sehen. Im firmeninternen Wiki, in dem die Dokumentation abgelegt ist, jedoch sehrwohl. Vielleicht sogar mit einem direkten Link auf das Abteilungs-Intranet, auf das man von außen gar keinen Zugriff hätte.

Es wirken also unterschiedliche Dinge auf eine Dokumentation ein:

Einflussfaktoren auf die Dokumentation

Dokumentation entsteht nicht im luftleeren Raum. Sie wird von technischen, organisatorischen und prozessualen Faktoren beeinflusst.

Doc-as-Code bedeutet daher nicht nur ein bestimmtes Tool oder Format zu wählen, sondern diese Einflüsse bewusst in eine strukturierte und wartbare Dokumentation zu übersetzen.

Damit man das alles erreicht, muss auch in der Dokumentation rund um die eigentliche Dokumentation echter Code geschrieben werden. Meist sind das Makros, die während des Generierens des Ausgabeformates interpretiert werden. Es können aber auch Pre-Prozessoren vonnöten sein, die vielleicht erst mal die Dokumentation scannen muss, um vielleicht zusätzliche Artefakte zu generieren.

Wer Dokumentation also ernst nimmt und einen gewissen Qualitätsanspruch an seine Software (und damit auch auf die Dokumentation) hat, der wird nicht umher kommen, sich Gedanken auf Ebene eines Softwareentwicklers zu machen.

Als direktes Beispiel kann auch diese Seite angewandt werden. Sie präsentiert eigentlich nur statischen Inhalt (ähnlich einer Dokumentation). Aber sie repräsentiert mich in unterschiedlichen Sichten. So enthält sie Seite z.B. auch meinen CV. Neben der Tatsache, dass im CV auch Informationen stehen, die auf der Website auch zu finden sind, will ich den CV sowohl als Website darstellen, als auch als PDF direkt downloadbar anbieten. Der von der Website direkt heruntergeladene CV sollte aber keine persönlichen Daten, wie Adresse, Telefonnummer enthalten. Dafür will ich - aus den gleichen Inhalten - aber mit zusätzlichen Inhalten, bei Bedarf ein anderes PDF generieren lassen können.

Diese Seite ist mit ASCIIDOC geschrieben. Entsprechend gibt es Makros, die mir beim Entscheiden, welche Inhalte wann und wie dargestellt werden sollen, helfen.

ifeval::["{backend}" == "pdf"]
=== Kenntnisse

include::{includesdir}/skills/skills_matrix.adoc[]
\
'''
endif::[]

Hier soll meine Kenntnis Matrix nur eingebunden werden, wenn das Ausgabeformat PDF ist.

An anderer Stelle wird die Matrix nur eingebunden, wenn das Ausgabeformat HTML ist

ifeval::["{backend}" == "html5"]
include::{includesdir}/skills/skills_matrix.adoc[]
endif::[]

Man sieht: an unterschiedlichen Stellen (Views), gleiches Dokument, das eingebunden wird.

Und da ich die Matrix auf der Website etwas fancier darstellen kann, als im PDF, entscheide ich im Dokument selbst noch mal, welche Form eingebunden werden soll.

ifeval::["{backend}" == "html5"]
include::./skills_matrix_site.adoc[]
endif::[]

ifeval::["{backend}" == "pdf"]
include::./skills_matrix_pdf.adoc[]
endif::[]

Also: unterschiedliche Zielgruppe, unterschiedliche Aufbereitung.

Wie sieht eine typische Doc-as-Code Pipeline aus?

Die Pipeline für eine Dokumentation kann natürlich im Detail unterschiedlich aussehen. Das hängt stark vom Umfeld ab. Das folgende Bild zeigt als Beispiel die Pipeline für diese Website:

Dokumentations Build-Pipeline

Man sieht als zentrale Komponente das Build System. Diese Website wird mit Gradle und asciidoctor gebaut. Das kann natürlich variieren. Z.B. könnte es noch andere Frameworks, wie z.B. die docToolchain vor oder rund um asciidoctor geben. Die Idee ist aber immer die gleiche:

  • Schreibe die Dokumenation als Code

  • Benutze Interpreten deiner Dokumentation, um

  • unterschiedliche Ausgabeformen der Dokumentation zu generieren

Key Takeaways

  • Code allein ist keine Dokumentation. Gute Software braucht auch Kontext, Entscheidungen und Architektur.

  • Dokumentation funktioniert nur ohne Medienbruch. Je näher sie am Code und am Entwicklungsprozess liegt, desto eher bleibt sie aktuell.

  • Doc-as-Code ist kein Tool – sondern eine Arbeitsweise. Dokumentation wird strukturiert, versioniert, automatisiert und wie Code gepflegt.

  • Automatisierung macht Dokumentation nachhaltig. Eine Build-Pipeline ermöglicht es, aus denselben Quellen verschiedene Ausgabeformate zu generieren.

Fazit

Dokumentation scheitert selten daran, dass Menschen nicht dokumentieren wollen. Sie scheitert meist daran, dass der Prozess nicht zu ihrem Arbeitsalltag passt.

Der Doc-as-Code Ansatz versucht genau dieses Problem zu lösen: Dokumentation wird dort geschrieben, wo auch der Code entsteht, mit denselben Werkzeugen, denselben Prinzipien und derselben Automatisierung.

So wird Dokumentation nicht zu einer lästigen Zusatzaufgabe – sondern zu einem natürlichen Teil der Softwareentwicklung.

Dokumentation ist kein Nebenprodukt der Softwareentwicklung – sie ist Teil davon.

Der Code zeigt was ein System tut. Dokumentation erklärt warum.