Dokumentation schreiben in 30 Minuten
Eine gute Dokumentation ist äußerst wertvoll, trotzdem scheuen die meisten Entwickler den Aufwand, sie zu schreiben. Dabei muss das Entwerfen einer guten Dokumentation weder langwierig noch aufwendig sein. 30 Minuten genügen in der Regel vollkommen.
- Golo Roden
Eine gute Dokumentation ist äußerst wertvoll, trotzdem scheuen die meisten Entwickler den Aufwand, sie zu schreiben. Dabei muss das Entwerfen einer guten Dokumentation weder langwierig noch aufwendig sein. 30 Minuten genügen in der Regel vollkommen.
Angenommen, ich beschäftige mich mit einem neuen Modul. Was interessiert mich dann? Sicherlich nicht, welche Bedeutung der vierte Parameter von einer relativ selten benötigten Funktion hat. Zunächst interessiert mich vor allem, ob das Modul die Aufgabe, die ich lösen muss, überhaupt bewältigen kann. Dazu möchte ich möglichst schnell einen Beweis sehen.
Das heißt, das erste, was mir eine Dokumentation vermitteln muss, ist die kurze und prägnante, aber präzise Information, worum es in einem Modul überhaupt geht. Danach möchte ich wissen, wie sich das Modul installieren lässt und wie ich es verwende. Dabei brauche ich noch nicht alle Informationen zu jedem erdenklichen Sonderfall, sondern ich will innerhalb von ein paar Minuten ein Erfolgserlebnis haben und sehen, dass ich in die richtige Richtung laufe.
Wenn ich dann sehe, dass die grobe Richtung stimmt, dann tauche ich tiefer in die Details ein. Dann möchte ich wissen, was das Modul alles kann und wie ich es verwende. Der springende Punkte dabei ist, dass ich wissen will, was das Modul macht. Das letzte, was mir erzählt, was ein Modul macht, ist eine API-Referenz.
Erzähl mir eine Geschichte!
Was ich stattdessen lesen will, ist ein Tutorial, das mich auf eine Reise mitnimmt und mir erklärt, wie das Modul zu benutzen ist. Dabei will ich von den allgemeinen zu den Spezialfällen kommen und nach und nach mehr lernen. Ich sage damit nicht, dass eine API-Referenz nicht ihren Wert und ihren Sinn hätte, sie taugt nur nicht als Einstieg, weil alles gleich behandelt wird: Ich sehe in einer Referenz nicht, welche Funktionen und Objekte wie miteinander zusammenhängen. Ich sehe nur eine flache Liste.
Interessanterweise ist das Schreiben einer Geschichte eine viel einfachere Sache als das Dokumentieren jeder einzelnen Funktion. Dazu muss man nämlich lediglich das niederschreiben, was man einem Verwender erklären würde: Es genügt, sich vorzustellen, man würde neben jemandem sitzen und erläutern, wie das Modul zu benutzen ist. Niemand würde in der Situation beginnen, eine API-Referenz zu rezitieren.
Ganz am Ende, wenn ich mit dem Modul dann glücklich geworden bin und weiß, dass es die Aufgabe erfüllt, die ich zu lösen hatte, dann mache ich mir vielleicht noch Gedanken, wie ich zu der Weiterentwicklung des Moduls beitragen kann, beispielsweise wenn ich einen Fehler gefunden habe. Dazu muss ich dann wissen, wie ich die Tests ausführe, ob es Coderichtlinien gibt und Ähnliches. Auch das gehört also in die Dokumentation.
Was heißt das nun für die Praxis?
Praktische Dokumentation
In meinem Unternehmen, the native web gibt es kein Modul, das nicht dokumentiert wäre. Jedem Modul, das wir schreiben, fügen wir eine Datei README.md hinzu. Das gilt für Code, den wir als Open Source veröffentlichen genauso wie für rein internen Code. Damit sind wir einerseits gewappnet, jeglichen Code jederzeit als Open Source veröffentlichen zu können, und helfen uns andererseits auch intern: Der erste Verwender von Code ist nämlich unser eigenes zukünftiges Selbst.
Jeder Entwickler kennt die Situation, dass man sich bei undokumentiertem Code bereits nach kürzester Zeit fragt, wie er zu verwenden war. Indem man jedes Modul mit Dokumentation ausstattet, stellt sich diese Frage nie wieder.
Dass wir die Dokumentation als Markdown-Datei schreiben, hat den Grund, dass wir sie auf dem Weg in die Versionsverwaltung einchecken können und man zu jedem beliebigen Codestand automatisch auch die zugehörige Dokumentation erhält. Außerdem fällt das Pflegen der Dokumentation leichter, wenn sie sich im gleichen Repository befindet, als wenn man dazu erst ein weiteres externes System bemühen muss.
Nach den bislang genannten Grundsätzen ist beispielsweise die Dokumentation des flaschenpost-Moduls geschrieben. Die README.md beginnt mit folgenden Zeilen:
# flaschenpost
flaschenpost is a logger for cloud-based applications.
> *A [/ˈflaʃənˌpɔst/](https://en.wiktionary.org/wiki/Flaschenpost) is a
„message written on a scrap of paper, rolled-up and put in an empty
bottle and set adrift on the ocean; traditionally, a method used by
castaways to advertise their distress to the outside world”.*
(from [Wiktionary](https://en.wiktionary.org/wiki/message_in_a_bottle))
## Installation
'''bash
$ npm install flaschenpost
'''
## Quick start
First you need to integrate flaschenpost into your application.
'''javascript
const flaschenpost = require('flaschenpost');
'''
Damit ist klar, was das Modul flaschenpost macht, wie es installiert und integriert wird. Als Nächstes folgt die Sektion Using a logger, in der beschrieben wird, wie man einen Logger erhält und ihn verwendet:
### Using a logger
Next, call the 'getLogger' function to acquire a logger. If you don't
provide a parameter flaschenpost identifies the caller automatically.
'''javascript
const logger = flaschenpost.getLogger();
'''
In rare cases you need to specify the caller manually, e.g. if you
wrap flaschenpost in your own logging module. In these cases, provide
'__filename' as parameter.
'''javascript
const logger = flaschenpost.getLogger(__filename);
'''
Then you can use the functions 'fatal', 'error', 'warn', 'info' and
'debug' to write log messages. Simply provide the message you want to
log as a parameter.
'''javascript
logger.info('App started.');
'''
Ich will an der Stelle nicht die gesamte Datei wiederholen, aber man sieht das Prinzip, wie sie aufgebaut ist. Nachdem am Ende die Details erklärt sind, wie sich die Logmeldungen an andere Systeme wie ElasticSearch schicken lassen, folgt noch ein kurzer Abschnitt zu der Frage, wie man die Codeanalyse und die Tests ausführt:
## Running the build
To build this module use [roboter](https://www.npmjs.com/package/roboter).
'''bash
$ bot
'''
Anschließend folgt noch die Lizenz, und das war's. Es gibt in dem Fall noch nicht einmal eine API-Referenz, da alle wichtigen Punkte bereits im Fließtext behandelt sind. Da das Modul eine sehr überschaubare Größe hat, passt die gesamte Dokumentation auf wenige Bildschirmseiten.
Nun kann man natürlich argumentieren, dass das für große Module nicht funktioniert. Das ist richtig, aber dem würde ich entgegnen, dass sich jedes größere Modul sinnvoll in kleinere Module zerlegen lässt. Häufig erhalte ich darauf als Antwort, dass das im vorliegenden Fall nicht möglich sei – tatsächlich habe ich noch keinen Fall erlebt, wo es nicht doch möglich gewesen wäre, ein größeres Modul in kleinere und dennoch sinnvolle Einheiten zu zerlegen.
Natürlich ist das Zerlegen von Code kein Selbstzweck, aber es ist viel einfacher, ein Modul zu dokumentieren, das aus lediglich fünf Dateien und insgesamt 500 Zeilen Code besteht, als eines, bei dem ein Vielfaches der Werte gilt. Abgesehen davon sind kleinere Module auch leichter zu warten, zu testen und zu pflegen. Und sie entsprechen der Philosophie von JavaScript und Node.js besser.
Eine Vorlage verwenden
Damit unsere Module in einem möglichst einheitlichen Stil dokumentiert sind, folgen unsere README.md-Dateien alle der zuvor genannten Struktur:
# <Add module name here>
<Add module description here>
## Installation
'''bash
$ npm install <Add module name here>
'''
## Quick start
...
## Running the build
To build this module use [roboter](https://www.npmjs.com/package/roboter).
'''bash
$ bot
'''
## License
<Add license text here>
Das ist zumindest die Vorlage, wenn wir mit der Arbeit an einem neuen Modul beginnen. Selbstverständlich passt eine Vorlage nicht immer und überall auf jede denkbare Dokumentation, aber auf dem Weg haben wir zumindest eine einheitliche Ausgangsbasis, die sich bei Bedarf immer noch anpassen lässt.
Fazit
Unsere Erfahrung mit JavaScript und Node.js in den vergangenen Jahren zeigt uns, dass wir mit dem gewählten Ansatz sehr gut arbeiten können: Das Schreiben von Dokumentation fällt leicht und geht schnell. Schon mehrfach waren wir sehr dankbar dafür, dass wir uns zu einem früheren Zeitpunkt die Zeit genommen haben, Dokumentation zu schreiben.
Unsere Erfahrung lehrt uns auch, dass diese Art von Dokumentation zumindest im Kontext von JavaScript und Node.js, wo (sehr) kleine Module favorisiert werden, hervorragend funktioniert und akzeptiert wird. Und das ist es doch, was am Ende zählt, denn was nützt die beste Dokumentation, die niemand liest?
tl;dr: Dokumentation zu schreiben muss nicht aufwendig und langatmig sein. Es genügt, eine Geschichte zu erzählen und den Verwender mit einem Tutorial abzuholen. API-Referenzen haben ihre Daseinsberechtigung, sind aber überbewertet. ()