Gestern Abend war es wieder einmal soweit. Das .NET Coding Dojo in München öffnete die Tore für alle .NET Enthusiasten, TDD Interessierte, CCD Jünger und neugierige Software-Entwickler.

Und das erste Münchener .NET Coding Dojo des Jahres startete wahrhaftig mit einem Paukenschlag! Erstmals überstieg die Teilnehmerzahl den Rahmen einer Dojo Session, so dass wir zwei Teams machen mussten (und wollten), die gegeneinander in einem "Dojo-Battle" antreten und ein Code Kata lösen sollten.

Nach einer kurzen Willkommens-Einwärm-Phase ging es auch schon zur Wahl des Code Kata's für den Abend. Zur Auswahl standen KataBowling, KataMinesweeper und der KataLocCounter in der C# Variante. Nach der kurzen Vorstellung der Code Kata's entschied sich die Dojo-Gemeinde für den KataLocCounter. Eine besonders erfrischende und spaßbringende Wahl, wie sich im Laufe des Abends herausstellen sollte.

Starke Teams denken, testen, zählen

Das Code Kata ist gewählt, die Aufgabe und Rahmenbedingungen erklärt, nun konnte es schon losgehen. Fast. Die Teams mußten noch formiert werden. Die wurden im Zählverfahren (wie denn sonst ;-)) aufgeteilt. Wie es der Zufall will, waren die Teamstärken gut verteilt.

Team 1 war stark besetzt mit der analytischen Expertise von Andre, den CCD- und .NET Guru's Ralf und Stefan. Hinzu kamen erfahrene Dojojaner wie Thomas und Christina, gestärkt mit einem Dutzend weiterer .NET-Entwickler.

Doch wer nun dachte, Team 2 wäre schwächer aufgestellt, der irrte sich gewaltig. Christian, ein Dojo-Gänger der ersten Stunde und kraftvoll vorandesignender C# Architekt, der durch zahlreiche Dojo's durchtrainierte Stefan, die geballte TDD/BDD-Erfahrung von Björn und ein starkes Dutzend .NET-Coder waren ein anspruchsvolles Lineup.

Die Teams waren aufgeteilt, das gedankliche Stretching und Warmup getan. Es konnte losgehen!

Jede Codezeile zählt

In einer ersten Phase wollten die Teams sich ein wenig detaillierter mit den Anforderungen an den Line-Counter auseinandersetzen, um eine "Design-Strategie" auszuarbeiten.

string code="Diese Zeile zählt!";
// Einzeilige Kommentare zählen nicht

// Dieser Kommentar und die leere Zeile davor zählen auch nicht
int count = 0; // Diese Zeile zählt natürlich!
bool countComments = false; /* Diese Zeile zählt auch */

/* So ein Kommentar
über mehrere Zeilen hinweg
zählt natürlich nicht als Code! */

Ein paar Kommentarbeispiele :-)

Interessante Erkenntnis hierbei: Man hat sich zwar mit den fachlichen Anforderungen und den daraus ergebenden Features bzw. Rahmenbedingungen auseinandergesetzt, dabei aber die Analyse und eine gemeinsame Implementierungsstrategie nicht wirklich erarbeitet. Geklärt war zumindest, dass es galt, Kommentare im Code zu erkennen und nicht mitzuzählen. Das Wie und eine gemeinsame Übereinkunft über die Strategie fiel bei beiden Teams "unter den Tisch".

Doch das war offensichtlich zunächst nicht weiter schlimm, denn es schien erstmal wichtiger, das die Teams in den TDD-Rythmus kommen. Die ersten Tests gingen traditionell etwas schwerer vom Kopf in die Tastatur über, doch nachdem man sich auf den Happy-Pfad im Testing und eine inkrementelle Auslieferung des Programmes geeinigt hat ging es dann flotter.

Das Ergebnis innerhalb der Count-Methode des Team 1 war bis dato recht überschaubar:

var lines = source.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

return lines
    .Select(x => x.Trim())
    .Where(x => !String.IsNullOrEmpty(x))
    .Where(x => !x.StartsWith("//"))
    .Count();

Soweit so gut.

Stolperstein Block-Kommentare

Nach den einfacheren Fällen trafen beide Teams mit den mehrzeiligen Block-Kommentaren auf eine etwas härtere Nuss, die es zu knacken galt. Wie sollte man denn die mehrzeiligen Kommentare erkennen? Vor Allem, wie sollte man dann mit besonders "außergewöhlichen" Kommentierungen umgehen?

int count = 1; /* mehrzeilige
kommentare können */ count++ /* herausfordernd sein */ ;

Außergewöhnliche Kommentare

An dieser Stelle holte die Teilnehmer die "zu kurze Analyse" zu Beginn wieder ein. Welche Strategie sollte man wählen? Die zeilenbasierte Verarbeitung aufgeben und zeichenbasiert arbeiten? Umschwenken auf schweißtreibende, aber mächtige Regular Expressions? Oder sogar eine Kombination von allem?

Das besondere und mich nicht überraschende: beide Teams wählten unterschiedliche Strategien. Während Team 1 die Eleganz des "Flows" der LINQ-Expression nicht aufgeben wollte und es mit Regular Expressions angereichtert hat, entschloss sich Team 2 für eine kleine Status-Maschine und einen Mix aus zeilen- und zeichenbasierter Verarbeitung.

Showdown

Nach knapp 3 Stunden war es dann soweit. Die Teams klopften die letzten Tests und Codezeilen ein, um sich dann im Schlußvoting dem gegnerischen Team zu stellen. Gespannt warteten die Teams auf den Code und die Resultate des Gegners.

Team 1 präsentierte zunächst das lauffähige Programm, danach das gute Dutzend Tests und den damit getriebenen Code. Auffällig: Der Code erschien dem Gegner auf den ersten Blick als kompakt und elegant.

Team 2 konterte prompt. Eine äußerst saubere Test-Suite, ein durch die differierende Implementierung etwas längerer Code und die Besonderheit, dass die Implementierung sogar (teilweise) Kommentar-Tokens innerhalb von Strings ignorieren konnte.

Ergebnis: Beide Lösungen waren unvollständig - aber gut vorangetrieben. Während Team 1 stärkeren Wert auf Auslieferbarkeit & Effizienz gelegt hatte, engagierte sich Team 2 mehr in den Bereichen saubere Tests & Funktionalität. Ausnahmsweise gab es beim ersten Dojo-Battle keinen Verlierer - beide Teams waren gleich stark.

Fazit: Ein wirklich gelungener Abend mit engagierten Teams, die trotz der Herausforderungen und Schwierigkeiten eine gute Leistung abgeliefert haben! Danke an alle Teilnehmer! Chapeau!


(c) Copyright . 1998 - 2013. Ilker Cetinkaya.