TODO (EJ) Ohne den Finger genau drauflegen zu können, finde ich die Sprache an vielen Stellen noch nicht knackig genug. Einge Formulierungen erscheinen mir komplizierter als notwendig. Bspw: - “den von uns durchgeführten” -> “unseren” - Unterschied zwischen Autor oder Code-Leser hier wichtig, oder reicht “Entwickler”? - “zur Ablage von” -> “für”

Bei den von uns durchgeführten Code-Analysen gilt ein besonderes Augenmerk den sog. Task-Tags. Bei Task-Tags handelt es sich um vom Team mehr oder minder einheitlich verwendeten Zeichenkenketten wie “TODO”, “FIXME” oder “HACK”. Diese werden verwendet, um Stellen zu markieren, an denen aus Sicht des Autors oder eines Code- Lesers noch Handlungsbedarf besteht. Dies ist eine sinnvolle, leichtgewichtige Technik, die wir selbst z.B. auch gerne zur Ablage von Review- Kommentaren verwenden. Problematisch werden die Task-Tags erst, wenn es bei der Markierung bleibt und niemals eine Handlung erfolgt. Da dies leider bei vielen Systemen der Fall ist, begegnen uns bei der Code-Analyse nahezu jeden Systems Task-Tags, die nicht nur einen hohen Unterhaltungswert haben, sondern vielfach auch auf ernsthafte Probleme hinweisen. Neben den allseits bekannten von der IDE-generierten Tags á la “TODO: auto-generated method stub”, staunen wir vor allem über Tags dieser Art:

  • TODO: Soll das so sein? Jetzt echt? Alle alten Sachen in die Tonne?
  • FIXME: temporary hack to pass the tests
  • TODO: Nicht benutzen, hat hier überhaupt nix verloren und wird falsch initialisiert !!!!!
  • TODO: REFACTOREN ! ich habe das jetzt einfache rüberkopiert, ist Müll so, aber ich kann das auf die Schnelle 1 Tag vor Releaseende nicht einfach mal so schnell umbauen

Ein kurzer Blick in die Historie der Datei verrät meistens, dass der betroffene Tag nicht erst seit gestern im System ist und vielfach schon mehrere Jahre vor sich hindümpelt. Insbesondere bei Tags wie dem Folgenden löst das dann nicht nur bei uns, sondern auch den Entwicklern und Projektleitern ein mulmiges Gefühl aus (diesen Tag haben wir im Oktober 2010 gefunden):

Veralteter Task-Tag

TODO (EJ) Ich würde hier “allen Entwicklungsteams” rauswerfen

Wir raten daher allen Entwicklungsteams, Task-Tags nur im Kontext eines (leichtgewichtigen) Prozesses einzusetzen, der sicherstellt, dass wichtige Erkenntnisse nicht wieder verloren gehen. Dieser Prozess sollte festlegen, wie Task-Tags auszusehen haben, d.h. welche Tags (“TODO”, “FIXME”, usw.) verwendet werden und welche zusätzliche Information mit diesen abgelegt werden soll. Aus unserer Sicht bietet es sich hierbei an, das Kürzel des Autors, z.B. “TODO (FD): das muss raus”, anzugeben, da es oft recht umständlich ist, diesen über das Versionsmanagement-System in Erfahrung zu bringen. Das Erstellungsdatum abzulegen ist bei einem vernünftigen Prozess Overkill, da dieser ja genau sicher stellen sollte, dass die Tags zeitnah wieder entfernt werden.

Um dies zu erreichen, sollten mit Hilfe eines geeignete Analysewerkzeugs zu festgelegten Zeitpunkten alle Task-Tags aus dem System extrahiert und bearbeitet werden. Dabei heißt “bearbeiten”, dass das, was der Tag beschreibt, entweder direkt umgesetzt wird, oder ein entsprechender Issue im Issue-Tracker erstellt wird. Der Issue-Tracker ist erfahrungsgemäß der bessere Ort zur Ablagen von Dingen, die erst zu einem späteren Zeitpunkt angegangen werden oder deren Abarbeitung lange dauert. Durch die Übertragung in den Issue-Tracker wird ein Task-Tag von einem U-Boot, das man leicht vergisst, zu einem vollwertigen Issue wieder jeder andere Bug oder Feature-Request auch. Der richtige Zeitpunkt für die Durchsicht vorhandender Task-Tags hängt vom Entwicklungsprozess ab. Bei agilen Projekten, lässt sich dies gut mit den Sprints oder Iterationen synchronisieren. Insbesondere bei stärker wasserfallartigen Projekten raten wir dringend davon ab, die Liste der Tags kurz vor dem Release durchzugehen, da dann kaum mehr Zeit für die Behebung und manchmal nicht einmal für die Übertragung in den Issue-Tracker bleibt. In kleinen bis mittleren System (<500kLoC) sollten beim Einsatz eines solchen Prozesses nie mehr als ein Dutzend Task-Tags im System vorhanden bleiben.

Falls sich in einem System bereits eine große Menge von Task-Tags angesammelt hat, gibt es unterschiedlichen Möglichkeiten damit umzugehen:

  • Boy-Scout-Rule: Entsprechend der Pfadfinder-Regel “Hinterlasse den Zeltplatz sauberer als du ihn vorgefunden hast”, werden Task-Tags immer dann adressiert (bearbeitet oder im Issue-Tracker abgelegt), wenn man Code anfasst, der Tags enthält. Ob man diese Regel für ganze Klassen/Dateien oder auf Ebene der Methode/Prozedur durchsetzt hängt sowohl von der Programmiersprache als auch der Güte der Systemstrukturierung ab. Erfahrungsgemäß ist bei wohlstrukturierten Java-Systemen die Klasse eine gute Ebene, bei C oder PL/SQL eignet sich die Methode/Prozedur meist besser, da sich sonst niemand mehr traut irgendwelche Änderungen vorzunehmen. Bei der regelmäßigen Extraktion der Task-Tags müssen dann natürlich Werkzeuge zum Einsatz kommen, die geändert Code von nicht- geändertem unterscheiden können.

  • Big-Bang: Alternativ ist auch ein Big-Bang-Vorgehen möglich, bei dem alle Task-Tags in einem Rutsch adressiert werden. Da dies bei großen Mengen von Task- Tags sehr zeitintensiv sein kann, eignen sich Projekte, die unter entsprechendem Zeitdruck stehen, typischerweise eher wenige für dieses Vorgehen. In jedem Fall ist zu vermeiden, dass die Tags “adressiert” werden, in dem sie einfach ohne weitere Prüfung gelöscht werden. Dies gilt es im Übrigen auch unbedingt zu überprüfen falls ein Dienstleister mit der Entfernung der Tags beauftragt wird.

Zusammenfassend ist festzuhalten, dass Task-Tags ein praktisches Hilfsmittel sind um Aufgaben zeitnah und sehr nah am Code festzuhalten. Wie unsere Entdeckungen bei zahlreichen Systemen aber immer wieder zeigen, sind sie definitiv kein sinnvoller Ersatz für ein strukturiertes Issue-Tracking und sollte auch nicht dafür missbraucht werden.

PS: Für diese Art von Task-Tags haben wir bisher leider keine vollautomatische Erkennung in unseren Werkzeugen implementiert:

Task-Totenkopf