TDD Workshop

January 8th, 2010

Im Rahmen der VSone Konferenz in München halte ich am 26. Februar 2010 einen Tagesworkshop zum Thema testgetriebene Entwicklung.

Der Workshop richtet sich an Entwickler, die einen leichten Einstieg in die testgetriebene Entwicklung suchen. Anhand zahlreicher Beispiele und Übungen wird die Vorgehensweise dargestellt und geübt. Dabei verwende ich Konzepte und Lernmethoden die sich in den Clean Code Developer Seminaren bewährt haben: die Teilnehmer sind intensiv in den Lernprozess eingebunden. Jemandem beim TDD zuschauen ist eine Sache; Ziel ist es, es selbst zu tun. Die Inhalte werden daher in Übungen vermittelt. Alle Übungen werden anschließend besprochen und mit den Teilnehmern diskutiert.

Details zu den Inhalten

Jetzt anmelden!

Kick it on dotnet-kicks.de

Jahresrückblick eines Clean Code Developers

December 22nd, 2009

Ziemlich genau vor einem Jahr ist die Clean Code Developer Initiative online gegangen. Ralf Westphal und ich hatten ursprünglich den 1.1.2009 angepeilt, sind dann aber schon ein paar Tage früher fertig geworden. Was sich dann so alles ereignet hat, hat uns wirklich überrascht. Angenehm glücklicherweise ;-)

Zunächst wurde nämlich schon das erste Clean Code Developer Camp in Hamburg gebucht, bevor wir mit den CCD Inhalten im Wiki komplett fertig waren. Das Camp lief über insgesamt 10 Tage, aufgeteilt auf 2 Wochen, die von einer kurzen Pause unterbrochen waren. Ein voller Erfolg! Dennoch beschlich uns das Gefühl, dass es zur “Druckbetankung” möglicherweise eine Ergänzung geben sollte. So haben wir die Idee der School of .NET diskutiert, durchaus auch öffentlich (siehe z.B. hier und hier und hier).

Bei der School of .NET geht es uns vor allem darum, zwischen den einzelnen Einheiten immer wieder Pausen einzulegen, in denen die Teilnehmer sich in ihrem Alltag mit dem gelernten auseinandersetzen können. Dies bietet dann auch gleich noch die Möglichkeit, zur Vertiefung des Stoffes Hausaufgaben lösen zu lassen. So wurde das Camp mit seinen 2 x 5 Tagen ergänzt durch die School mit 7 x 2 Tagen (die ersten Kurse waren etwas unregelmäßiger, da waren auch mal Einzeltage dabei). Im kommenden Jahr bieten wir sowohl das Camp als auch die School wieder an. In München sind noch ein paar Plätze frei, Details siehe hier.

Eine Konstante hat sich in beiden Formen bewährt: das Team-Teaching. Beim Camp sind Ralf Westphal und ich beide über die komplette Seminardauer anwesend, bei der School of .NET haben wir auch ab und zu Tage mit nur einem Trainer eingeschoben. Von Teilnehmern haben wir immer wieder das Feedback gehört, dass das Team-Teaching sehr zum Erfolg beiträgt. So wirkt die Tatsache, dass Ralf und ich inhaltlich auch schon mal unterschiedliche Standpunkte vertreten authentisch und bereichert das Seminar um nützliche Diskussionen. Schließlich ist im Bereich der Softwareentwicklung nach wie vor vieles im Fluss und auch wir als Trainer entwickeln uns weiter. Ferner haben die Teilnehmer es als hilfreich empfunden, Inhalte ab und zu in unterschiedlichen Nuancen erklärt zu kriegen. Manchmal hilft schon eine etwas andere Formulierung. Die Teilnehmer solcher Seminare haben ja schließlich einen unterschiedlichen Background, nicht jeder lernt genau so wie sein Kollege, mancher mag es lieber etwas abstrakter, der andere sehr konkret.

Im Jahr 2009 habe ich auch wieder einige Gelegenheiten für Vorträge gehabt. Dabei waren sowohl .NET Usergroups als auch Konferenzen wie die prio oder die XPdays. Eine Übersicht dazu gibt’s hier.

Neben Team-Teaching hatten Ralf und ich auch die Gelegenheit zur Team-Beratung. Wir haben mehrfach den ersten Beratungstermin bei einem neuen Kunden zu zweit bestritten. Vier Augen sehen bekanntlich mehr als zwei, gerade bei der Bestandsaufnahme und der Frage, welche Schritte zur Verbesserung wir empfehlen, erwies sich dies als vorteilhaft.

Bei Heise Developer haben wir die Gelegenheit erhalten, eine kleine Serie zu Brownfield Projekten zu schreiben. Der erste Teil und der zweite Teil sind bereits erschienen, fünf weitere werden noch folgen.

Rückblickend betrachtet war das Jahr 2009 wirklich sehr spannend. Die Resonanz auf die Clean Code Developer Initiative ist durchweg sehr positiv. So hat z.B. die Xing Gruppe inzwischen mehr als 1000 Mitglieder. Und wir haben noch einige Ideen…

Ausblick auf 2010

Im nächsten Jahr stehen natürlich auch schon einige Termine fest. Da ist zum einen die OOP zu nennen, bei der Ralf und ich die Clean Code Developer Initiative vorstellen werden. Im Rahmen der VSone halte ich neben einem Vortrag zu Domain Driven Design einen Tagesworkshop zur Testgetriebenen Entwicklung (test-driven development, TDD).

Unter dem Titel priodotnetpro.powerday bieten Ralf und ich CCD Inhalte an insgesamt 3 Tagen. Der erste Tag, der powerday, ist ein eher klassischer Konferenztag, bei dem den Teilnehmern zahlreiche Vorträge geboten werden. Etwas anders als üblich ist die Tatsache, dass die Teilnehmer vorher eine Publikumsaufgabe lösen können. Damit nehmen sie zum einen an einer Verlosung wertvoller Preise teil. Zum anderen wird genau diese Problemstellung über den Tag hinweg unter verschiedenen Aspekten beleuchtet. Hat man die Aufgabe selber gelöst, erhält man so Rückmeldung zur eigenen Vorgehensweise.

Am zweiten Tag, dem powerworkshop, bieten wir die Möglichkeit, einen Tag lang an den CCD Bausteinen zu schnuppern. In kleinen Gruppen werden an dem Tag einige Prinzipien und Praktiken vermittelt und anhand von Beispielen und Übungen gelernt.

Der dann folgende dritte Tag bietet powercoaching: mehrere Teams kommen mit ihren ProblemenHerausforderungen zu uns und präsentieren ihre Fragen anhand eines konkreten Projektes. Wohlgemerkt geht es dabei um ein echtes Projekt, nicht um Beispiele oder Übungen. Jedes Team erhält Zeit sein Problem darzulegen, wir geben anschließend Hinweise zu Lösungen. Der Clou daran: die Teams präsentieren sich mit ihren Fragen vor den anderen Teams. Das bedeutet, jedes teilnehmende Team erhält nicht nur Input zu seinen eigenen Fragen, sondern kann auch an den Fragen und Antworten der anderen Teams teilhaben.

Die drei Tage können einzeln gebucht werden, so kann sich jeder das heraussuchen was für ihn am besten passt.

Ich bin jedenfalls schon sehr gespannt, was das Jahr 2010 bringen wird. Allen Lesern wünsche ich frohe Feiertage und einen guten Start in das neue Jahr.

Kick it on dotnet-kicks.de

Clean Code Developer auf der OOP 2010

December 11th, 2009

Vom 25. – 29. Januar 2010 findet in München wieder die OOP statt. Diesmal sind Ralf Westphal und ich dort mit einem Vortrag über die Clean Code Developer Initiative vertreten.

Abstract

Durch lückenhafte Anforderungen und Termindruck ist schlechte Softwarequalität oft nicht begründbar. Zu diagnostizieren ist vielmehr die breite Abwesenheit eines unverbrüchlichen Fundaments an Prinzipien und Praktiken für die Softwareentwicklung. Die Clean Code Developer (CCD) Initiative möchte das ändern. Der Vortrag stellt das CCD-Wertesystem mit seinen Bausteinen, Prinzipien und Praktiken vor, erklärt die schrittweise Arbeit an seinen Modulen und diskutiert mit den Zuschauern über Nutzen, Chancen und Grenzen eines solchen Wertesystems.

Kick it on dotnet-kicks.de

.NET Open Space 2009 in Leipzig

October 20th, 2009

Ein intensives und anstrengendes Wochenende liegt hinter mir. Nachdem wir am Freitag die Räume im MedienCampus vorbereitet hatten, konnte am Samstag morgen der 2. .NET Open Space in Leipzig starten. Mit deutlich mehr Teilnehmern als im letzten Jahr war meine größte Sorge, ob die Sessionplanung reibungslos funktionieren würde. Nicht dass ich Zweifel am Open Space Format hätte, aber je mehr Teilnehmer Sessions vorschlagen können, desto größer ist die Gefahr, dass sich der Prozess zu lange hinzieht.

Anders als im letzten Jahr haben wir die Vorschläge dieses Jahr direkt in ein Zeit- und Raumraster einsortiert. Dadurch stand der Sessionplan bereits fest, nachdem alle Vorschläge genannt wurden. Erfreulicherweise kam es dabei zu keinen zeitlichen Überschneidungen, so dass alle Sessions auch tatsächlich stattgefunden haben.

Zwei Themen die mir schon in vorangegangenen Open Spaces wichtig waren haben auch dieses Jahr wieder eine Rolle gespielt: Command/Query Separation und Service Bus. Bei der Command/Query Separation liegt leider eine doppelte Verwendung des Begriffes vor: neben dem Prinzip, dass eine Methode entweder ein Command oder eine Query sein sollte, wird damit auch ein Architekturpattern bezeichnet. Es wird in Systemen mit sehr hohen Anforderungen an Durchsatz verwendet. Wie auch schon bei anderen Veranstaltungen fehlten Teilnehmer, die bereits ein System mit diesem Pattern gebaut haben, so dass die Diskussion eher theoretisch war. Beim nächsten Open Space sollte sich das langsam ändern ;-)

Beim Thema Service Bus stand vor allem die Frage im Vordergrund, wann sich der Aufwand lohnt, einen Service Bus einzusetzen. Schließlich geht es dabei nicht nur um die korrekte Anwendung neuer Funktionalität, sondern auch um Installation und Betrieb der entsprechenden Infrastruktur. Meine klare Empfehlung, diese Infrastruktur erst einzusetzen, wenn mehrere Bounded Contexts zu verbinden sind, wurde prinzipiell geteilt. Wir haben auch einfachere Publish/Subscribe Ansätze diskutiert, die beispielweise in Frameworks wie Prism oder Caliburn zum Einsatz kommen. Da der Einsatz von Publish/Subscribe dort der besseren Entkopplung dient, ist der Einsatz in jedem Fall empfehlenswert.

Auch beim Thema Service Bus habe ich den Eindruck, dass zu einem nächsten Open Space eine exemplarische Implementierung vorliegen sollte, damit die Diskussion konkreter wird. Vielleicht finden sich ja ein paar Leute die Lust haben, eine Beispielanwendung zu bauen?

Der 2. NET Open Space war aus meiner Sicht wieder ein voller Erfolg. Vielen vielen Dank an Torsten Weber, Alexander Groß und Marcel Hoyer, die den Hauptteil der Organisation übernommen haben. Ein weiteres Dankeschön an Maik den Hausmeister für seine tatkräftige Unterstützung.

Nach dem Open Space ist vor dem Open Space ;-)

Kick it on dotnet-kicks.de

Neues Design jetzt online

October 9th, 2009

Ich habe das Design meiner Website http://lieser-online.de überarbeiten lassen. Nun sind zwar noch ein paar Wiederholungen in den Dateien, das Menü steht beispielsweise in allen HTML Files, aber das macht erstmal nichts. Agile Entwicklung heißt schließlich, in Iterationen arbeiten.

Kick it on dotnet-kicks.de

FullTrust auf Netzwerk Share

October 7th, 2009

Weil ich immer wieder danach suche: wie lautet der Befehl, um FullTrust auf eine Netzwerk Share einzurichten?

caspol -q -machine -addgroup 1 -url file://z:/* FullTrust
Kick it on dotnet-kicks.de

Static Gateway Pattern [endlich-clean.net]

October 4th, 2009

Oft stellt man bei Unit Tests die nach der Implementierung erstellt werden fest, dass statische Klassen oder Methoden verwendet werden. Dabei stellt sich dann die Frage, wie man diese im Test isolieren kann. Ein einfaches Beispiel soll die Problematik verdeutlichen:

   1: public class Task

   2: {

   3:     private string name;

   4:     private string projectName;

   5:  

   6:     public Task CreateNewTask(string taskName) {

   7:         return new Task {

   8:             name = taskName,

   9:             projectName = ProjectManager.CurrentProjectManager.CurrentProject().Name

  10:         };

  11:     }

  12:  

  13:     public string Name {

  14:         get { return name; }

  15:     }

  16:  

  17:     public string ProjectName {

  18:         get { return projectName; }

  19:     }

  20: }

Der Knackpunkt ist in Zeile 9 zu finden. Hier wird auf einen ProjectManager zugegriffen, der offensichtlich eine statische Instanz in Form eines Singleton enthält.

Um nun die Methode CreateNewTask testen zu können, muss der Aufruf an den ProjectManager isoliert werden. Dies geht auf einfache Weise, in dem man das sogenannte static gateway Pattern anwendet. Dazu muss die Klasse, welche die statische Methode enthält, modifiziert werden. Zunächst die Variante der Klasse, die im Test nicht isoliert werden kann:

   1:  

   2: public class ProjectManager

   3: {

   4:     private static ProjectManager currentProjectManager;

   5:     private static Project currentProject;

   6:  

   7:     public static ProjectManager CurrentProjectManager {

   8:         get {

   9:             if (currentProjectManager == null) {

  10:                 currentProjectManager = new ProjectManager();

  11:             }

  12:             return currentProjectManager;

  13:         }

  14:     }

  15:  

  16:     public Project CurrentProject() {

  17:         if (currentProject == null) {

  18:             currentProject = new Project();

  19:         }

  20:         return currentProject;

  21:     }

  22: }

Hier liegt das Problem im static Property CurrentProjectManager in den Zeilen 7-14. Dort wird nämlich beim ersten Zugriff eine Instanz der Klasse ProjectManager erstellt. Dieses Singleton wird dann in allen weiteren Aufrufen zurück geliefert. Um nun Verwender dieser Klasse testen zu können, müssen wir das Verhalten der Klasse ProjectManager im Test jedoch beeinflussen können. In der oben gezeigten Implementierung kann die Klasse im Test jedoch nicht durch eine Attrappe ersetzt werden. Also schaffen wir uns diese Möglichkeit in dem wir folgende Methode ergänzen:

   1: public static void SetCurrentProjectManager(ProjectManager projectManager) {

   2:     currentProjectManager = projectManager;

   3: }

Damit können wir im Test eine Attrappe eines ProjectManagers erzeugen und in die Klasse injizieren.

Im zweiten Schritt ist es in der Regel erforderlich, ein Interface auf die Klasse zu definieren. Dies ist immer dann notwendig, wenn die Methoden, deren Verhalten im Test verändert werden soll, nicht virtuell sind, da sie dann nicht überschrieben werden können. Im konkreten Beispiel müsste ein Interface für die Klasse ProjectManager erstellt werden. Andernfalls kann das für den Test gewünschte Verhalten der Attrappe nicht implementiert werden. Mit Refaktorisierungswerkzeugen wie ReSharper lässt sich das automatisieren (Extract Interface).

Steht das Interface zur Verfügung, müssen die Verwender der Klasse auf das Interface umgestellt werden. Mit ReSharper läßt sich auch das automatisieren (Use Base Type where Possible).

Zuletzt kann dann im Test eine Attrappe anstelle des “echten” ProjectManagers verwendet werden:

   1:  

   2: [TestFixture]

   3: public class TaskTests

   4: {

   5:     private IProjectManager projectManager;

   6:  

   7:     [SetUp]

   8:     public void Setup() {

   9:         projectManager = MockRepository.GenerateMock<IProjectManager>();

  10:         ProjectManager.SetCurrentProjectManager(projectManager);

  11:         projectManager.Expect(x => x.CurrentProject()).Return(new Project("n1"));

  12:     }

  13:  

  14:     [Test]

  15:     public void Task_name_is_set_correct() {

  16:         var task = Task.CreateNewTask("t1");

  17:         Assert.That(task.Name, Is.EqualTo("t1"));

  18:     }

  19:  

  20:     [Test]

  21:     public void Task_project_name_is_set_correct() {

  22:         var task = Task.CreateNewTask("");

  23:         Assert.That(task.ProjectName, Is.EqualTo("n1"));

  24:     }

  25: }

Fazit: mit kleinen Umbauarbeiten können statische Methoden auch im Test verwendet werden. Bei einer test-first Vorgehensweise wären die Schwächen dieses Designs jedoch sofort aufgefallen, ein späterer Umbau zugunsten der Testbarkeit wäre dann nicht erforderlich.

Kick it on dotnet-kicks.de

Von Code Katas, Root Causes und zu kurzen Blog Posts [endlich-clean.net]

September 18th, 2009

Gestern habe ich über meine Erkenntnisse beim Bearbeiten zweier Code Katas berichtet. Ralf hat nun eine Root Cause Analysis angestellt und dabei einen wichtigen Aspekt herausgearbeitet:

TDD ist ein Werkzeug, das mir den Weg zu wartbarem Code für ein gegebenes Modell zeigt. TDD ersetzt die Modellierung aber nicht.

Mal davon abgesehen, dass er nicht “wartbar” meint sondern “evolvierbar”, stimme ich dieser Erkenntnis uneingeschränkt zu. Allerdings glaube ich, dass mein Blog Post eventuell etwas zu kurz geraten ist und daher eine andere Erkenntnis untergegangen ist. Denn ich hatte von Anfang an ein Modell der Lösung vor Augen. Dies soll keine Rechtfertigung sein, denn in der Tat passiert es mir auch manchmal, dass ich mit TDD loslege, ohne eine solches Modell.

Im konkreten Fall bei der KataPotter hatte ich zwei Probleme:

  • Umsetzung meiner algorithmischen Idee
  • Refaktorisieren der Lösung so dass sie “clean” wird

Ich habe die Kata Beschreibung komplett gelesen, bevor ich mit Tests oder gar Implementierung begonnen habe. Daher war mir von Anfang an bewusst, dass die Kata nicht gelöst werden kann, ohne eine algorithmische Idee, ein Modell, zur Lösung zu haben. Die Herausforderung dabei ist folgende:

Jeder Band kostet 8 EUR. Ein Set bestehend aus 5 unterschiedlichen Bänden ergibt einen Rabatt von 25%, Sets aus 4 Bänden 20%, Sets aus 3 Bänden 10% und Sets aus 2 Bänden 5%. Der Rabatt wird nur auf die Bände gewährt, die in einem Set enthalten sind, also nicht auf den gesamten Warenkorb! Das führt dazu, dass man nicht einfach die größtmöglichen Sets zur Berechnung heranziehen kann, sondern verschiedene Varianten durchprobieren muss und dann die Kombination mit dem niedrigsten Gesamtpreis verwendet.

Beispiel: der folgende Warenkorb kann zu unterschiedlichen Sets kombiniert werden.

  • 2 x Band 1
  • 2 x Band 2
  • 2 x Band 3
  • 1 x Band 4
  • 1 x Band 5

Daraus ergeben sich folgende Möglichkeiten:

  • 1 x 5er Set plus 1 x 3er Set
  • 2 x 4er Set

Die zweite Variante ist preiswerter.

So weit so gut. Meine algorithmische Idee sah von Anfang an folgendermaßen aus: in einer Hashmap werden die Bücher (Key) jeweils mit ihrer Menge (Value) abgelegt. Anschließend werden mögliche Sets gebildet und der Gesamtpreis des Warenkorbs gebildet. Dabei werden mehrere Durchläufe vorgenommen und die maximale Setgröße jeweils beschränkt. Im ersten Durchlauf sind 5er, 4er, 3er und 2er Sets zulässig. Im zweiten Durchlauf nur 4er, 3er, 2er, dann nur 3er und 2er, etc.

Beim jeweiligen Durchlauf zähle ich in der Hashmap also, wieviele Einträge vorhanden sind, deren Value größer 0 ist. Diese bilden ein Set. Dann wird deren Value um 1 reduziert und erneut gezählt. Dies so lange, bis alle Values 0 sind.

Das Modell sieht also bildlich so aus: nehme jeweils das größte Set aus dem Warenkorb und berechne seinen Preis. Addiere diesen Setpreis zum bisherigen Gesamtpreis. Wiederhole dies solange, bis der Warenkorb leer ist. Um das Minimum zu ermitteln, lasse erst Sets bis 5 zu, dann nur Sets bis zur Größe 4, etc.

Klingt alles ganz einfach (hoffe ich jedenfalls), erfordert in der Implementierung aber ein paar Schleifen und Hilfsvariablen. Und darin lag mein erstes Problem: in der konkreten Umsetzung der Idee. Zum Beispiel mussten die Values in der Hashmap jeweils um 1 reduziert werden. Dabei habe ich immer wieder eine Fehlermeldung erhalten, die (sinngemäß) besagte, dass die Hashmap innerhalb des foreach geändert worden wäre. Nach ein paar erfolglosen Versuchen ist mir gedämmert, dass ich garkeine Hashmap benötige, sondern ein Array mit den Mengen völlig ausreicht.

Doch dabei schlug dann mein zweites Problem zu: es tauchten Hilfsvariablen auf. Erst eine, dann noch eine. Der Code sah nicht “schön” aus. Also begann ich zu Refaktorisieren, obwohl noch nicht alle Tests liefen. Und das war meine eigentliche Erkenntnis, die ich gestern in meinem Blog Post zum Ausdruck bringen wollte: beginne nicht zu früh mit dem Rafaktorisieren.

Ich begann nämlich, die Implementierung zu verändern, kriegte die häßlichen Konstrukte aber nicht lesbarer hin. Also ließ ich es erstmal sein und stellte die Implementierung fertig. Und siehe da: plötzlich war es ganz einfach die Implementierung so zu refaktorisieren, dass sie leicht verständlich wurde und die Hilfskonstrukte verschwanden.

Fazit: TDD mit Modell im Kopf (oder auf Papier) funktioniert. Und ich bin sicher, dass meine Implementierung ohne die Tests noch zahlreiche Fälle falsch berechnen würde. Dadurch, dass die Tests vor der Implementierung da waren habe ich mir den Frust erspart, zu glauben ich wäre fertig, um dann festzustellen, dass es doch noch Fälle gibt, die von meiner Implementierung falsch berechnet werden.

Kick it on dotnet-kicks.de

Domain Driven Design Seminar mit Eric Evans

September 16th, 2009

Am vergangenen Montag hatte ich das Vergnügen, ein 1-tägiges Überblickseminar zu Domain Driven Design mit Eric Evans und Hans Dockter zu besuchen. Es war das erste Seminar, das von der Domain Language Germany GmbH in Deutschland veranstaltet wurde.

Obwohl ich mich schon lange mit Domain Driven Design befasse, habe ich in diesem einführenden Seminar neue Anstöße erhalten. Vor allem der Teil zu strategic design hat mir durch die gut gewählten Beispiele einige neue Aspekte vor Augen geführt. Dazu werde ich bei Gelegenheit ausführlicher berichten.

Mit der Domain Language Germany GmbH ist DDD nun “offiziell” in Deutschland angekommen.

Kick it on dotnet-kicks.de

Coding Katas: FizzBuzz und Potter [endlich-clean.net]

September 16th, 2009

Ich habe gestern zwei Coding Katas bearbeitet:

Die erste ist inhaltlich sehr einfach. Es geht dabei vor allem darum, testgetrieben in Baby-Steps zu arbeiten. Ich hatte dabei keine Probleme.

Bei der zweiten wird’s schon schwieriger. Die erste Herausforderung besteht darin, die Anforderung zu verstehen. Es geht um eine Rabattierungsregel für Bücher. Hat man die Regeln mal verstanden, kommt die zweite Herausforderung, nämlich die Frage nach der algorithmischen Umsetzung.

Da ich es gewohnt bin, testgetrieben zu arbeiten, hatte ich mit den ersten Schritten keine Probleme. Die ersten Tests waren schnell erstellt und haben die Implementierung schnell in die richtige Richtung getrieben. Dann kamen jedoch die komplizierteren Beispiele an die Reihe und ich habe länger mit der Implementierung gekämpft. Eine Idee für die Herangehensweise hatte ich schnell, aber bei der Umsetzung war ich geneigt, bereits zu früh “schönen” Code schreiben zu wollen. Als ich das gemerkt habe, habe ich zunächst eine Implementierung runtergeschrieben, welche die Anforderungen erfüllte. Beim weiteren Ergänzen von Tests traten dann noch einige Unzulänglichkeiten zu Tage, aber irgendwann war die Implementierung korrekt. Erst dann habe ich mit dem Refaktorisieren weiter gemacht. Das ging dann viel einfacher als bei meinem Versuch, schon die unfertige Implementierung zu refaktorisieren.

Fazit: vor allem die zweite Kata war für mich eine gute Übung. Ich habe erkannt, dass ich mit dem Refaktorisieren tendenziell zu früh beginne. Das werde ich weiter beobachten.

Kick it on dotnet-kicks.de