Quellcodedokumentation
Quellcode kann auf verschiedenen Ebenen dokumentiert werden, um dessen Lesbarkeit und Wiederverwendbarkeit zu erhöhen. Hierzu betrachten wir zwei Mechanismen:
- Inline-Kommentare: Kommenatare im Quellcode, um dessen Funktionsweise zu erklären, als Antwort auf die Frage: «Wie funktioniert das?»
- Dokumentationskommentare Kommentare am Quellcode, um dessen Verwendung zu erklären, als Antwort auf die Frage: «Wie kann ich das verwenden?»
Inline-Kommentare
In JavaScript/TypeScript gibt es zwei Arten von Inline-Kommentaren:
- Zeilenkommentare, die mit
//anfangen und bis zum Ende der Zeile gehen. - Blockkommentare, die mit
/*anfangen und mit*/auf der gleichen oder auf einer andere Zeile enden.
Hierzu ein Beispiel:
Info
Die Platzierung der Kommentarbegrenzungen /* und */ auf der gleichen bzw. auf separaten Zeilen ist Gegenstand vieler sinnloser Diskussionen, an denen sich mit Vorliebe Entwickler ohne belastbare Evidenz beteiligen. Oft arten solche Diskussionen in Beschimpfungen und Handgreiflichkeiten aus – oder enden mit dem Kompromissvorschlag, dass diese Platzierung eben Geschmackssache sei. Dies ist paradox, zumal sich Entwickler mit gutem Geschmack nicht an solchen Diskussionen beteiligen.
Kommentare werden vom Compiler ignoriert und können nicht verschachtelt werden. Einige Texteditoren und Entwicklungsumgebungen heben einige häufig in Kommentaren verwendete Schlüsselwörter hervor:
TODO: Hier gibt es noch etwas fertigzustellen oder zu verbessern.NOTE: Hier ist etwas besonderes zu beachten.FIXME: Hier muss noch ein Problem (Fehler) gelöst werden.HACK: Hier wurde aus einem besimmten Grund unsauber gearbeitet.
Beispiele:
Diese Schlüsselwörter sind jedoch nicht standardisiert, sondern bloss eine Konvention. Bei deren Verwendung sollte man prüfen, ob man nicht besser direkt eine Verbesserung am Quellcode vornehmen soll, als dessen Unzulänglichkeit zu dokumentieren. Ist dies nicht möglich, sollten solche Kommentare durch ein Ticket (Fehlerbericht, Task, usw.) begleitet oder dadurch ersetzt werden.
Quellcode sollte so klar geschrieben sein, dass er selbsterklärend ist. Beim Schreiben von Quellcode darf man davon ausgehen, dass der Leser die Programmiersprache und die verwendeten Libraries und Frameworks kennt. Faustregel:
Kommentare sollen sagen, was der Code nicht sagen kann.
Oder:
Kommentiere nur, was du nicht codieren kannst.
Sehr guter Quellcode kann über weite Strecken ohne Kommentare auskommen. Im Umkehrschluss ist eine hohe Kommentardichte im Quellcode eher ein schlechtes Zeichen. Dies sind jedoch nur Heuristiken, d.h. Faustregeln.
Wenn man erklärende Kommentare schreibt, sollte man eher die Frage beantworten, warum man etwas auf eine bestimmte Weise tut, und nicht, was hier überhaupt passiert. Auch das ist nur eine Faustregel.
Dokumentationskommentare
Im Gegensatz zu erklärenden Inline-Kommentaren sollte man Dokumentationskommentare konsequent schreiben. Diese erklären, wie eine bestimmte Quellcode-Einheit (eine Konstante, eine Funktion, eine Klasse, eine Eigenschaft, eine Methode oder ein Modul) verwendet wird, und was dabei zu beachten ist.
Im Gegensatz zu Inline-Kommentaren werden Dokumentationskommentare auch ausserhalb vom Code gelesen. Hierzu verarbeitet man den kommentierten Quellcode mit speziellen Werkzeugen, um Dokumentation daraus zu erzeugen.
Da Dokumentationskommentare die Verwendung und nicht die interne Funktionsweise von Quellcode dokumentieren, kann man sich mit der Dokumentation von öffentlichen (public) und exportieren (export) Elementen begnügen. Einige Organisationen verlangen, dass sämtliche öffentlichen Bezeichner (Klassen, Eigenschaften, Methoden) dokumentiert sein müssen. Andere sind pragmatischer und verwenden Dokumentationskommentare nur an Orten, wo die Verwendung der Codeeinheit nicht selbsterklärend ist.
JSDoc
Verschiedene Programmiersprachen und -umgebungen stellen verschiedene Mechanismen und Werkzeuge für Dokumentationskommentare zur Verfügung. In JavaScript/TypeScript kommt JSDoc (siehe auch die für TypeScript spezifische Referenz) zum Einsatz.
Ein JSDoc-Kommentar beginnt mit der Zeichensequenz /** und endet mit */. Dazwischen stehen ein- oder mehrzeilige Kommentare.
Deno hat Unterstützung für JDSoc über den Befehl deno doc eingebaut, das u.a. Dokumentation als HTML ausgeben kann (deno doc --html).
JDSoc-Kommentare beinhalten neben erklärendem Text auch Annotationen bzw. Tags. Das sind spezielle Schlüsselwörter mit einer bestimmten Bedeutung. Im folgenden wird kurz auf einige ausgewählte Annotationen eingegangen. Eine vollständige Übersicht bietet die JSDoc Reference.
Weitere Annotationen/Tags werden im weiteren Modulverlauf bei Bedarf eingeführt.
Die Dokumentation einer TypeScript-Datei kann folgendermassen extrahiert und auf der Kommandozeile betrachtet werden:
Parameter und Rückgaben: @param und @returns
Bei Funktionen und Methoden sollen die Funktionsparameter und Rückgabewerte dokumentiert werden. Hierzu das dokumentiere FizzBuzz-Beispiel von vorher (fizz-buzz.ts):
Die Dokumentation beginnt mit einer Beschreibung der Funktion und nach welchen Regeln sie operiert. Dabei steht das Verhältnis zwischen übergebenem Argument und Rückgabewert im Vordergrund.
Mit @param wird der Funktionsparameter x bezeichnet. Hier wird er zusätzlich innerhalb geschweifter Klammern mit dem Typ annotiert. Nach dem Namen des Parameters folgt (getrennt von einem Dash) dessen Erklärung.
Mit @returns wird der Rückgabetyp und dessen Bedeutung angegeben.
Info
Da die Parameter- und Rückgabetyp bereits im TypeScript-Code annotiert worden sind, kann man sich die Datentypen in den JSDoc-Annotationen auch sparen!
Die generierte Dokumentation sieht dann folgendermassen aus:
Möchte man die Dokumentation als HTML betrachten, kann man dies mit Deno folgendermassen bewerkstelligen:
Dadurch wird ein Ordner docs/ erzeugt, die u.a. eine Datei index.html enthält, die nun im Browser geöffnet werden kann.
Info
Die Funktion fizzBuzz wurde exportiert, damit sie in der HTML-Dokumentation unter Symbols erscheint!
Missbilligter Code: @deprecated
Bestehender Code, der nicht mehr verwendet werden sollte, den man aus Gründen der Rückwärtskompatibilität aber noch nicht löschen kann, kann man mit @deprecated markieren. Damit kündigt man an, dass Verwendungen dieses Codes ersetzt werden sollten:
Die Implementierung buildName hat den Nachteil, dass sie bei fehlendem middleName einen Abstand von zwei Zeichen zwischen Vor- und Nachnamen anzeigt. Da sie öffentlich und Teil einer exportierten Klasse ist, wird sie möglicherweise an vielen Orten verwendet. Deshalb kann sie nicht ohne weiteres gelöscht werden.
Symbole, die als @deprecated markiert sind, werden im Code oft durchstrichten dargestellt (z.B. als buildName). Dadurch erhält man beim Bearbeiten von Client-Code einen Anreiz, den Aufruf zu ersetzen.
Markiert man ein Symbol als @deprecated, sollte man eine entsprechende Alternative bereitstellen und diese erwähnen. Hierzu kann man die Annotationen @see oder @link verwenden:
Urheber: @author
Möchte man sich als Urheber eines bestimmten Symbols auszeichnen, kann man hierzu die @author-Annotation verwenden:
Gibt man neben seinem Namen auch eine E-Mail-Adresse an, sollte diese in spitzen Klammern angegeben sein, da das @sluz im obigen Beispiel sonst als Annotation interpretiert wird.
Viele JSDoc-Annotationen wie @class, @type oder @private die in JavaScript sehr hilfreich sein können, sind in TypeScript nicht nötig, da diese Informationen bereits aus dem Code extrahiert werden können.