ReSharper Search and Replace with Pattern

August 9th, 2010

Endlich bin ich dazu gekommen, das ReSharper Feature Search and Replace with Pattern auszuprobieren.

Die Herausforderung

Es nervt mich, wenn ich über älteren Code stolpere, in dem ich noch mit Assert.AreEqual gearbeitet habe. Aktuell verwende ich lieber Assert.That, weil das für mich besser lesbar ist. Also habe ich nach einer Möglichkeit gesucht, die eine in die andere Variante zu ändern. Auf Knopfdruck versteht sich.

Die Lösung

Mit ReSharper ist die Lösung ganz einfach. Man legt sich ein entsprechendes Replace Pattern an:

  • Find: Assert.AreEqual($expected$, $actual$);
  • Replace: Assert.That($actual$, Is.EqualTo($expected$));

Die beiden Platzhalter $expected$ und $actual$ werden als Parameter definiert. Editieren kann man das Pattern über die Menüfunktion ReSharper | Find | Search with pattern…

Edit Highlighting Pattern

Das coolste an diesem Feature: man kann dem Pattern eine Pattern severity zuordnen, z.B. “Show as warning”. ReSharper weist dann in Quellcodedateien auf gefundene Instanzen des Patterns hin und bietet einen Quickfix an. So wird durch einen einfachen Druck auf Alt-Enter eine Assertion im “alten Stil” aktualisiert.

Kick it on dotnet-kicks.de

Coding Dojo Berlin

August 9th, 2010

Letzte Woche waren Ralf und ich zu Gast bei der Berliner Dojo Gruppe. Mike Bild und Marco Rasp haben das Dojo organisiert, ihnen dafür ein großes Dankeschön!

Obschon wir am Tag zuvor unseren ersten Probelauf für den prio.walk absolviert haben, waren wir in Berlin wieder gut auf den Beinen. Vom Alex ging es gut 3km zu Fuß zum Veranstaltungsort. Dort erwartete uns eine Gruppe von 15 Entwicklern. Wir haben vorgeschlagen, die Kata BankOCR zu lösen. Da die Gruppe diese Kata noch nicht bearbeitet hatte, wurde der Vorschlag angenommen. Anschließend haben wir kurz erläutert, dass wir den weiteren Verlauf des Dojos in drei Phasen aufteilen möchten:

  • In der ersten Phase geht es um das Verstehen der Anforderungen sowie den Entwurf einer Lösung.
  • Die zweite Phase befasst sich mit der Implementierung nach TDD.
  • In der dritten Phase reflektiert die Gruppe über den Abend.

Dabei sehen wir in der ersten und letzten Phase den Schwerpunkt auf echter Gruppenarbeit, also alle arbeiten gemeinsam. In der mittleren Phase wollten wir den Schwerpunkt eher auf die Arbeit eines einzelnen legen.

Los ging es mit den Anforderungen. Am Flipchart wurden Beispiele für die Ziffern angeschrieben und die Gruppe fragte nach, bis alle Unklarheiten beseitigt waren. Dabei zeigte sich schon, dass manchmal die Begriffe durcheinander gingen. Zahl und Ziffer auseinander zu halten ist nicht wirklich schwer, aber im Eifer des Gefechts geht da schon mal etwas Präzision verloren. Daher haben wir vorgeschlagen, die Begriffe der Domäne “BankOCR” zu sammeln und in Beziehung zu setzen. So kamen Begriffe wie OCRZiffer, OCRZahl, Textzeile, OCRZeile und weitere zusammen. Durch diese Diskussion wurde das Verständnis der Gruppe für die Problemstellung vertieft. Vor allem wurde aber eine gemeinsame Sprache, die sogenannte ubiquitous language) geschaffen, in der die Gruppe sich nun viel präziser unterhalten konnte. Die Gefahr von Missverständnissen und aneinander-vorbei-Reden wurde dadurch reduziert.

Letzter Schritt der ersten Phase war dann der Entwurf. Wir erachten es für notwendig, vor dem Kodieren einen Entwurf zu erstellen. In größeren Kontexten mag es dabei um Komponenten gehen, in kleineren Aufgabenstellungen, so wie bei dieser, eher um Klassen und Methoden. Die Gruppe machte unterschiedliche Vorschläge zur Notation eines Entwurfs am Flipchart. Dabei wurden nicht nur grafische Entwürfe diskutiert, sondern auch versucht, rein textuell zu arbeiten. Es ergab sich eine lebhafte und sehr fruchtbare Diskussion über die Art und Weise des Softwareentwurfs. Das hat uns sehr gefreut, denn wir haben zu keinem Zeitpunkt den Eindruck gehabt, dass die Gruppe lieber mit TDD losgelegt hätte. Wir hatten uns im Vorfeld gefragt, ob die Gruppe sich darauf einlassen würde, vor der Implementierung zu planen. Erfreulicherweise stand das nicht wirklich in Frage.

Tja und dann? Kritiker werden uns nun vielleicht vorhalten, wir hätten gar kein Coding Dojo veranstaltet. Denn die Zeit war uns davon gelaufen, wir haben keine einzige Zeile Code geschrieben. Die Gruppe hat dies in der nachfolgenden Reflexion jedoch nicht bemängelt. Im Gegenteil. Alle haben zum Ausdruck gebracht, an diesem Abend etwas gelernt zu haben. Und Spaß hat es auch gemacht. Ob man den Abend nun Coding Dojo oder Workshop oder bunten Abend nennt… mir ist es fast egal. Wichtig ist festzuhalten, dass wir zu keiner Zeit die Absicht hatten, das Kodieren unter den Tisch fallen zu lassen. Dann hätten wir dies im Vorfeld kommuniziert und nicht mehr von einem Coding Dojo gesprochen. Es hat sich so entwickelt und die Gruppe war zufrieden. Ich gestehe aber, wir haben im Vorfeld überlegt, ob wir nicht mal ein Architektur Dojo anbieten sollen. Dass es in Berlin ungewollt zur Premiere kam ist vielleicht eine Bestätigung dafür, dass es nicht immer ums Kodieren gehen muss.

Dass der Entwurf so lange gedauert hat, war vor allem der Tatsache geschuldet, dass die Gruppe noch keine gemeinsame Entwurfssprache gefunden hatte. Wenn die Gruppe solche Entwurfsphasen in ihren Dojos häufiger gemacht hat, wird konsent darüber entstehen, wie Entwürfe am Flipchart notiert werden. In unseren Seminaren führen Ralf und ich die Gruppen in dieser Phase sehr stark. Hier im Dojo haben wir nicht versucht, der Gruppe “unsere” Notation aufzudrängen, wir haben sie nicht einmal vorgeschlagen. Dadurch konnte die Vielfältigkeit innerhalb der Gruppe zum Vorschein kommen. Auch das haben die Teilnehmer als sehr angenehm und lehrreich empfunden.

Nach dem Dojo haben wir den Abend noch beim Bierchen ausklingen lassen. Und dann stand noch eine kleiner Fußmarsch zurück zum Alex an. Mir taten hinterher ordentlich die Füße weh ;-)

Kick it on dotnet-kicks.de

Brownfield / Legacy Code

August 5th, 2010

Nach meinem Urlaub hier ein kurzes Update über zwischenzeitlich erschienene Artikel zum Thema Brownfield bzw. Legacy Code.

Im Blog der Firma TypeMock ist die englische Übersetzung eines Artikels von mir erschienen.

Der Originalartikel “Teile und teste: Tests von asynchronem Code” ist in Heft 08/2010 der dotnetpro erschienen. Der Artikel befasst sich mit der Frage, wie asynchroner Code automatisiert getestet werden kann. Neben architekturellen Fragen geht es dabei auch um die Frage, wie man mit internen/sealed Klassen des .NET Frameworks umgeht.

Desweiteren ist der vierte Teil der 7-teiligen Brownfield Serie, die ich gemeinsam mit Ralf Westphal schreibe, bei Heise Developer erschienen. Im Artikel Komplexität bewältigen durch Differenzierung geht es um die Frage, wie man eine Anwendung zerlegen kann, um vom “großen Klumpen Matsch” zu kleineren Einheiten zu kommen.

Kick it on dotnet-kicks.de

iPad v3.2.1 behebt die WiFi Probleme leider nicht

July 16th, 2010

Heute morgen hatte ich noch gehofft, die WiFi Probleme des iPad in Zusammenhang mit einer Fritz!Box und einem Fritz!Repeater gehörten der Vergangenheit an. Leider muss ich inzwischen aber feststellen, dass dem nicht so ist. Wirklich zuverlässig funktioniert das WLAN nur mit einem Apple AirPort. Schade eigentlich…

Kick it on dotnet-kicks.de

Wohin mit den Tests?

July 2nd, 2010

Bislang habe ich immer dafür plädiert, Tests und Implementierung in getrennten Projekten unterzubringen. Im Sinne von Separation of Concerns sind Tests und Implementierung nun mal zwei unterschiedliche Belange, die daher nicht im selben Projekt untergebracht werden sollten. Im Kern scheint mir das Problem darin zu liegen, die Dateien mit den Tests sauber von den Dateien mit der Implementierung zu trennen.

Auf der anderen Seite gehören Test und Implementierung zusammen. Schon bei der ersten Implementierung arbeitet man ständig an beidem und auch bei Änderungen sind in vielen Fällen Änderungen/Ergänzungen sowohl an den Tests als auch der Implementierung erforderlich. Um diese Zusammengehörigkeit auszudrücken, verwende ich in den Projekten die gleiche Verzeichnisstruktur. So weiß ich, wo die zu einer Implementierung gehörenden Tests zu suchen sind. Aber mir fällt schon auf, dass dies mit Disziplin und Pflege verbunden ist. Ordnet man den Code im Implementierungsprojekt anders an, muss man dies im Testprojekt nachziehen. Speziell das Umbenennen von Klassen führt häufig dazu, dass die Tests nicht umbenannt werden. Würden diese näher bei der Klasse stehen, würde einem das Problem eher auffallen.

Nun ist das Problem bei der Komponentenorientierten Architektur nicht wirklich groß, denn da sind die einzelnen Projekte überschaubar klein. Jede Komponente besteht in der Regel aus wenigen Klassen, meist eine Hand voll, selten deutlich mehr als 10. Da führt die Unterbringung von Tests und Implementierung in getrennten Projekten nicht so schnell zum Chaos.

Dennoch, angeregt durch Gespräche mit Teilnehmern des Open Space in Karlsruhe, an dem ich selbst leider nicht teilnehmen konnte, und angeregt durch die folgende Bemerkung von Ilker, möchte ich es mal anders ausprobieren:

weil es schlichtweg nicht mehr zeitgemäß ist, Tests vom SUT zu trennen. Je näher sie zueinander stehen, um so besser.

Die Frage ist also, wie schafft man es, dass die Tests möglich nahe bei der Implementierung stehen, andererseits aber eine klare Abgrenzung möglich ist. Eine mögliche Lösung heißt: Hierarchien bilden. Ralf hat in einem Blogpost in einem anderen Kontext schon auf vsCommands und die Möglichkeiten der Gruppierung hingewiesen. Mit vsCommands ist es möglich, Dateien zu gruppieren, so wie Visual Studio es mit partiellen Klassen macht. Auf diese Weise habe ich gerade mal die Datenstruktur Queue<T> implementiert und muss sagen, dass mir die dadurch entstandene Projektstruktur gut gefällt:

image

Jetzt stehen die Tests zur Klasse Queue unmittelbar darunter. Wenn ich sie nicht sehen möchte, kann ich sie zuklappen. Sehr schön.

Eine Frage bleibt allerdings noch: die Tests landen jetzt in der Assembly, die eigentlich nur die Implementierung enthalten sollte. Ist das egal? Kriegt man das im Buildprozess mit einfachen Mitteln behoben?

Kick it on dotnet-kicks.de

TDD 2.0

July 1st, 2010

Gestern habe ich den Standpunkt vertreten, dass Refaktorisieren im Test-Driven Development meiner Ansicht nach an der falschen Position im Prozess steht. Ferner habe ich erwähnt, dass vor dem Kodieren immer eine Planung stehen sollte. Diesen Vorschlag möchte ich etwas präzisieren.

TDDv2

In der Abbildung kann man sehen, dass der Prozess aus zwei Schleifen besteht. Im Inneren liegt der TDD Prozess. Im Gegensatz zur weit verbreiteten Ansicht vertrete ich die Meinung, dass Refaktorisieren jeweils am Anfang eines TDD Zyklus stehen sollte. Bevor ich den nächsten Test schreibe sollte ich überlegen, ob der Code durch Refaktorisieren verbessert werden kann. Verbessern meint hier, dafür zu sorgen, dass Prinzipien eingehalten werden und nicht gegen Werte verstoßen wird. Mein persönlicher Standpunkt zu Prinzipien, Praktiken und Werten ist bekanntlich unter clean-code-developer.de dokumentiert. Wer mag, orientiert sich daran, diskutiert mit Ralf und mir darüber oder findet seine eigenen Prinzipien und Werte. Warum ich glaube, dass Refaktorisieren am Anfang besser aufgehoben ist als am Ende habe ich gestern bereits beschrieben. Eine wichtige Annahme dabei ist, dass vor dem Kodieren eine Planung steht.

Mit der Planung beginnt die äußere Schleife. Nachdem ein Entwickler oder ein Team die Anforderungen geklärt hat (eine weitere interessante Herausforderung), sollte durch Planung ein Entwurf entstehen. Planung ist ein kreativer Prozess, bei dem die Gedanken freien Lauf haben sollen. Am besten nutzt man die Planungsphase sogar als Gelegenheit, mal von der Konsole aufzustehen und stellt sich ans Whiteboard. Mindestens aber sollte diese Planung auf Papier erfolgen, nicht am Rechner. Arbeiten am Rechner sind eher linear. Allemal wenn Code ins Spiel kommt. Der muss in einer gewissen Reihenfolge eingegeben werden und streng der Syntax genügen. Das behindert den freien Fluss der Ideen. Das Ziel der Planung ist es, das anstehende Gesamtproblem in Teilprobleme zu zerlegen. Das geht selbst bei so simpel anmutenden Aufgabenstellungen wie FizzBuzz, wie Ralf in seinem Blogpost sehr schön gezeigt hat.

Diese Planung dient nicht dazu, im Sinne von big-design-upfront gleich die Architektur für die gesamte Anwendung zu erstellen. Sie dient dazu, die Implementierung einer überschaubaren Anforderung zu planen. Um mal eine zeitliche Größenordnung zu nennen: die anschließend anstehende Implementierung nimmt einen Zeitraum im Bereich weniger Stunden in Anspruch.

Es gibt zahlreiche Gelegenheiten, diese Vorgehensweise mal auszuprobieren. Jeder Entwickler kann es für sich tun. Anregungen zu Übungen gibt es beispielsweise hier bei der dotnetpro. Nächste Woche startet in München das erste Clean Code Developer Praktikum. Auch dort werden wir nur mit Planung kodieren. Ziel dieses Praktikums ist unter anderem, unsere Vorgehensweise zu reflektieren. Im September starten wieder unsere Clean Code Developer Seminare. Und wer mal “für lau” in der Gruppe planen möchte, kann die Coding Dojos am 5.8. in Berlin oder am 19.10. in MünchenNürnberg nutzen.

Happy planning!

Kick it on dotnet-kicks.de

Refaktorisieren im TDD Prozess

June 30th, 2010

Inzwischen ist das TDD Mantra “Red/Green/Refactor” nicht mehr ganz unbekannt. Die Grundidee:

  • Schreibe einen Test – Red
  • Implementiere gerade soviel, dass der Test erfolgreich durchläuft – Green
  • Räume auf – Refactor

Entwickler die beginnen, sich mit Test Driven Development zu befassen, sehen die größte Herausforderung darin, die Reihenfolge von Implementierung und Test umzudrehen. Das ist in der Tat nicht immer einfach und erfordert Disziplin. Man muss sich zunächst mal auf dieses Experiment einlassen, um den tatsächliche Nutzen zu erkennen. Der liegt nämlich nicht nur in einer verbesserten Korrektheit, sondern vor allem in einer besseren Evolvierbarkeit. Das liegt daran, dass TDD einen starken Einfluss darauf hat, wie man seinen Code strukturiert. Denn es entsteht, oft wird behauptet ganz von alleine, gut testbarer Code. Meiner Erfahrung nach verbessert sich die Qualität des Codes zwar nicht so ganz von alleine, aber ich bestreite nicht, dass schon allein die Reihenfolge, erst Test, dann Implementierung einen positiven Einfluss auf die Codequalität hat. Deutlich besser wird die Qualität durch einen vorgelagerten Planungsschritt. Damit rede ich nicht dem “Big Design Upfront” das Wort, sondern ich meine, als Entwickler müssen wir uns die Zeit nehmen, vor dem Codieren ein paar Skizzen auf Papier zu machen.

Angeregt durch einen Artikel in der aktuellen Ausgabe der Visual Studio One möchte ich aber etwas zum Refaktorisieren los werden. In dem Artikel war eine Abbildung zur Vorgehensweise bei TDD abgedruckt. Nach kurzer Suche stolperte ich bei Wikipedia über eine ähnliche Abbildung. File:Test-driven development.PNGDas Bild beschreibt TDD als Prozess. Was mir sofort auffiel ist die Tatsache, dass es auf dem “Repeat” Pfad vom Refaktorisieren zurück zum nächsten Test keine Entscheidung gibt. Zwischen Test und Implementierung liegt eine Entscheidung: man geht erst zur Implementierung über, wenn man einen Test geschrieben hat, der fehlschlägt. Auch beim Übergang von der Implementierung zum Refaktorisieren kommt es zu einer Entscheidung. Diesmal geht es erst weiter zum Refaktorisieren, wenn alle Tests erfolgreich verlaufen. Doch dann die Überraschung: vom Refaktorisieren geht es einfach so wieder zurück zum nächsten Test. Da stellt sich mir doch die Frage, wann bin ich denn mit dem Refaktorisieren fertig? Und in der Tat taucht diese Frage bei Entwicklern in der Praxis ebenfalls auf, ohne dass sie sich den Prozess anhand eines solchen Bildes bewusst machen. Und auch beim Coding Dojo in München im Rahmen des dotnetpro-powerday kam kurz die Diskussion auf, ob denn nach der Implementierung nicht refaktorisiert werden solle. Die Frage ist also ganz offensichtlich nicht nur, wann bin ich fertig mit dem Refaktorisieren, sondern soll ich überhaupt refaktorisieren?

Meine These dazu: das Mantra Red/Green/Refactor suggeriert etwas Falsches. Da steht Refaktorisieren nämlich jeweils am Ende, nach der Implementierung. Es suggeriert, dass man immer nach der Implementierung refaktorisieren solle. Und das halte ich für falsch. Allemal, wenn beim Refaktorisieren nicht zwischen Mikro und Makro unterschieden wird. Mikrorefaktorisierungen wie etwa das Reformatieren des Quellcodes mit dem Ziel, die Klammern alle an der richtigen Position zu haben oder das Umbenennen eines Bezeichners, etc. stehen möglicherweise desöfteren nach der Implementierung an. Aber die größeren Refaktorisierungen eben nicht. Damit meine ich beispielsweise Änderungen an Zuständigkeiten; so etwas wie das Aufbrechen einer Klasse in zwei, mit dem Ziel, das Single Responsibility Principle (SRP) einzuhalten. Oder auch das Aufteilen einer Methode in mehrere. Das sind alles Refaktorisierungen, für die ich einen triftigen Grund benötige. Dabei bitte ich zu berücksichtigen, dass ich wie oben erwähnt, Verfechter von Planung bin. Wenn ich mich vor dem ersten Test mit einem Stück Papier hinsetze entstehen selten Strukturen, die hinterher einer größeren Refaktorisierung bedürfen.

Mein Vorschlag: das Mantra sollte etwas anders angeordnet werden. Es sollte lauten [Refactor]/Red/Green. Dabei sollen die eckigen Klammern andeuten, dass Refaktorisieren vor dem nächsten Test nicht in allen Fällen, aber oft erforderlich ist. Der Vorteil: nun habe ich konkrete Anhaltspunkte, ob ich Refaktorisieren muss bzw. wann ich damit fertig bin. Gelingt es mir nicht, eine neue Anforderung umzusetzen, weil die Struktur des Quellcodes dafür ungeeignet ist, habe ich einen Grund zu refaktorisieren. Sobald ich in der Lage bin, den nächsten Test zu schreiben, ohne dabei Prinzipien zu verletzen, bin ich fertig mit dem Refaktorisieren.

Eine Hinweis zum Schluss: die testgetriebene Entwicklung ist ein komplexer Prozess, den man nicht mit einem Mantra aus drei Wörtern vollständig beschreiben kann. Mir ist selbstverständlich klar, dass man nach der Implementierung kurz inne halten sollte um zu prüfen, ob kleine Mikrorefaktorisierungen anstehen. Diese sind aber so unspektakulär, dass sie keines der drei Worte im Mantra schon komplett für sich beanspruchen sollten. Wenn also bei TDD von “Refactor” die Rede ist, dann ist es wohl sinnvoll, damit die aufwändigeren strukturellen Refaktorisierungen zu bezeichnen. Und die gehören für mich an den Anfang statt ans Ende.

Kick it on dotnet-kicks.de

Gedanken zu Dojos

June 26th, 2010

Nachdem in den Blogs von Steffen und Ilker bereits über verschiedene Aspekte von Dojos diskutiert wurde habe ich den Eindruck, dass ein Aspekt der mir persönlich wichtig ist, bei diesen Diskussionen noch nicht beleuchtet wurde oder sogar misverstanden ist. Es geht mir dabei um den dargestellten Konflikt zwischen den “Codern” und den “Knoblern”. Dabei beziehe ich mich konkret auf das Dojo im Rahmen der dotnetpro powerdays in München. Ich und andere aus der “letzten Reihe” haben in diesem Dojo den Einwand gebracht, wir mögen doch vor dem ersten Test ein klein wenig planen. Leider konnte ich mich mit diesem Vorschlag nicht durchsetzen. Dabei sehe ich folgende Probleme:

  1. Die Beschlüsse wurden per Abstimmung herbeigeführt. Das halte ich für suboptimal. Zum einen, weil die Alternativen nicht inhaltlich diskutiert wurden. Dadurch konnten diejenigen, die den Vorschlag ablehnten, nicht wirklich deutlich machen, aus welchem Grund sie ihn ablehnen. So wurde ich am Lernen gehindert. Denn selbstverständlich kann ich ja auf dem falschen Dampfer sein. So musste ich mich auf das Experiment, direkt mit einem Test zu beginnen einlassen. Das Ergebnis ist bekannt. Ich war nicht damit zufrieden. Und ich bin immer noch überzeugt, dass wir mit etwas mehr Planung weiter gekommen wären. Dazu später mehr. Zum anderen halte ich Abstimmungen in Dojos für suboptimal, weil es neben dem Konsens noch den Konsent gibt. Eine Grundidee dabei: so lange niemand etwas wirklich gewichtiges gegen einen Vorschlag einzuwenden hat, wird er angenommen. Damit wird erreicht, dass Minderheiten nicht per Abstimmung ohne Argumente abgebügelt werden. Vielleicht gab es ja inhaltlich gewichtige Einwände gegen etwas mehr Planung. Ich habe sie bislang leider nicht erfahren.
  2. Ich war nicht konsequent genug, hätte versuchen sollen besser darzulegen worum es mir geht. Einen Schuh muss ich mir selber anziehen: ich habe vielleicht nicht wirklich deutlich gemacht, was ich mit “Planung” genau gemeint habe. Es wäre einfach gewesen, denn ich selbst habe mir eine Skizze angefertigt. Diese hätte ich auch an die Flipchart malen können. Vielleicht wäre dann klar geworden, dass es mir nicht um Big Design Upfront geht.

Was ich hier mit “Planung” meine, möchte ich deutlich abgrenzen vom Begriff der “Knobler”. Bei der Kata BankOCR gab es nichts zu knobeln. An den wenigen Diskussionen die sich inhaltlich mit der Lösung der Aufgabe befassten, konnte man erkennen, dass ganzEntwurfKataBankOCR offensichtlich alle Beteiligten eine Vorstellung ihres Lösungswegs im Kopf hatten. Mir geht es darum, diese diffuse Vorstellung explizit zu Papier zu bringen. Zum einen, um mir Klarheit darüber zu verschaffen und darüber nachzudenken, ob der gewählte Weg zum Ziel führt. Zum anderen, um in der Gruppe eine gemeinsame Diskussionsbasis zu schaffen. Meine SKizze war in wenigen Minuten angefertigt. Das nebenstehende Bild zeigt meine Skizze vom Dojo in München. Ich glaube  nicht, dass eine solche Skizze der Gruppe schwer gefallen wäre oder sie lange aufgehalten hätte. Durch eine solche Skizze wäre aber jedem klar gewesen, wo wir stehen, wovon wir sprechen. Und wir hätten anhand der Skizze überlegen können, wo wir mit dem ersten Test beginnen. Stattdessen wurde munter drauf los gecoded und irgendwann erkannt, dass wir offensichtlich von “innen nach außen” entwickelt haben.

Ich möchte betonen, dass ich keinen Konflikt sehe, zwischen der testgetriebenen Entwicklung und einer Planung vorab. Und ich spreche im Kontext dieser Kata nicht von Architektur. Es geht um das Design der Lösung, um die Zerlegung des Problems in Teilprobleme. Meinen Code entwickle ich ausschließlich testgetrieben. Völlig egal, ob es sich dabei um Produktionscode oder Beispiele für Artikel oder Vorträge handelt. Der einzige Unterschied zur Vorgehensweise beim Dojo ist, dass ich vorher eine Skizze mache. Immer! Denn in Zeiten, in denen ich das nicht gemacht habe, hatte ich am Ende ein Ergebnis, mit dem ich nicht ganz zufrieden war. Seit ich vorher plane, hat sich meine Codestruktur deutlich verbessert. Ferner kann ich dann viel entspannter loslegen, weil ich stehts weiß, wo ich stehe. Ferner ist die Qualität der Tests besser, da Teilaspekte isolierter getestet werden. Da ich mir nicht sicher war, ob meine Beobachtung richtig war und das bessere Ergebnis an der Vorplanung lag, habe ich zeitweise die Planung wieder weggelassen. Heute bin ich mir sehr sicher, dass ich mit Planung besser entwickle als ohne.

Damit möchte ich nun nicht behaupten, dass dies der einzig richtige Weg sei. Ich möchte lediglich darauf hinweisen, dass meiner Einschätzung nach in der einschlägigen Literatur zu TDD die Planung zu kurz kommt. Und die von mir besuchten bzw. durchgeführten Dojos haben mir ebenfalls gezeigt, dass es ohne Planung schwieriger ist, zum Ziel zu kommen. Einen weiteren Hinweis geben mir die Seminare und Workshops die ich in den letzten Monaten, meist gemeinsam mit Ralf Westphal, gehalten habe. Auch dort hat sich die Planung als vorteilhaft gezeigt.

Die Planung auf einem Stück Papier hat gegenüber dem “sofort loscoden” meiner Einschätzung nach den Vorteil, dass es ein nicht-linearer Prozess ist. Auf dem Papier kann ich wild springen, meinen Ideen freien Lauf lassen, Dinge verbinden, schnell etwas ergänzen oder auch wieder wegstreichen. Ganz anders ist die Arbeit an einem Test. Dies ist ein linearer Prozess. Ich bin gezwungen, den Code in einer bestimmten Reihenfolge einzugeben. Bevor ich überhaupt eine Zeile tippen kann, muss mindestens ein Projekt aufgesetzt werden. Das mag in trivialen Beispielen ebenso trivial sein, oft ergibt sich die Projektstruktur aber erst aus der Planung. Die Vorgehensweise beim TDD ist linear. Ohne dass ich vorher in einem kreativen nicht-linearen Prozess Ideen gesammelt und sortiert habe befinde ich mich in diesem linearen Prozess gefangen. Denn ich habe ständig die Sorge, dass ich eigentlich nicht genug von der möglichen Lösung weiß. Und oft genug kommen Probleme um die Ecke, die einen zur Umkehr zwingen. So war es auch beim Dojo in München. Wir haben irgendwann gemerkt, dass etwas nicht stimmt. Diese Erkenntnis hat mir meine Skizze bereits viel früher gebracht.

Nun will ich aber nicht nur Behauptungen aufstellen und von Alternativen schreiben, sondern auch anbieten, es mal anders zu versuchen. Der genaue Rahmen ist mir noch nicht klar, aber es wird Gelegenheit dazu geben, mal ein Dojo mit Planung durchzuführen. Ich werde rechtzeitig darauf hinweisen.

Kick it on dotnet-kicks.de

Kann man mit dem iPad bloggen?

June 5th, 2010

Natürlich kann man. Technisch gesehen. Aber geht es praktisch? Ich meine, geht vor allem das Schreiben mit dieser merkwürdigen Tätschel-Tastatur? Jep, geht. Aber was viel besser geht, ist Lesen. Denn das Schreiben längerer Texte ist ohne echte Tastatur schon etwas gewöhnungsbedürftig. Aber obacht, ich meine nicht wirklich “echte Tastatur” im Sinne von Hardware – ein vollständiges Tastaturlayout würde schon einiges verbessern. So fehlen die “german umlaute” genauso wie diverse Satzzeichen. Natürlich kann man diese alle irgendwie erreichen, aber das flotte Schreiben wird so schon arg gebremst. Die vorhandenen Tasten lassen sich zügig mit mehreren Fingern bedienen. Ich tippe auch sonst nicht mit allen 10 Fingern, aber mit mehr als nur ein oder zwei allemal. Und das geht auf dem iPad auch, wenn ich es auf den Beinen liegen habe.

Wirklich gut gehen Dinge wie MindMaps mit iThoughtsHD oder Graphen mit Instaviz. Dabei kommt es mehr auf Touchgesten an, weniger auf Text.

Absolut toll ist Instapaper. Alle längeren Texte im Web schicke ich damit auf mein iPad. So muss ich nicht alles am Rechner lesen, sondern kann mich gemütlich mit dem iPad auf’s Sofa setzen. Und offline geht’s mit Instapaper auch.

Wegen der Tastatur muss ich das iPad wohl jailbreaken. Mal sehen ob es dann bessere Layouts gibt.

Fazit: ich würde das iPad sofort wieder kaufen. Absolut coole Maschine mit Potential zu drastischen Veränderungen unserer Mediennutzung.

Kick it on dotnet-kicks.de

Microsoft behindert komponentenorientierte Architektur – ein wenig

May 20th, 2010

Update: Danke an Mathias für sein Stichwort WPF User Control Library

Warum ist es im aktuellen Visual Studio 2010 nicht möglich, in einem DLL-Projekt eine WPF Form zu erzeugen? Mint WinForms geht’s, mit WPF nicht. Es scheint so, als fehle Microsoft das Vorstellungsvermögen, dass jemand seine GUI in DLLs auslagert. Genau das ist aber bei komponentenorientierter Architektur praktisch immer der Fall.

Der Vollständigkeit halber noch meine Definition von “komponentenorientierter Architektur”: eine Komponente ist eine binäre Funktionseinheit mit separatem Kontrakt. Binär meint hier, dass eine Komponente nicht im Quelltext verwendet wird, sondern die Referenz auf eine binäre Form, sprich eine Assembly, hergestellt wird. Separater Kontrakt bedeutet, dass die Exportschnittstelle der Komponente in einer separaten Assembly liegt. Somit besteht jede Komponente aus mindestens zwei Assemblies. Eine enthält den Kontrakt, eine weitere die Implementierung. Natürlich wird die Implementierung von Tests begleitet, die wiederum in eigenen Assemblies liegen. In einer komponentenorientierten Architektur ist die Komponente die kleinste Funktionseinheit, um die sich Architekten kümmern. Alles was darunter liegt, insbesondere Klassen, liegt unter dem Radar der Architekten.

Doch zurück zum Tooling. Die komponentenorientierte Architektur hat den Vorteil, dass die Komponenten aus denen eine Anwendung besteht, untereinander klar definierte Beziehungen haben. Denn diese Beziehungen sind von den Architekten während der Planung eines Features definiert worden. Komponentenbeziehungen entstehen also nicht “aus versehen” sondern immer geplant. Nur so ist gewährleistet, dass es im Laufe der Zeit nicht zu undurchschaubaren Abhängigkeiten kommt. Natürlich muss dazu jede Komponenten eine klar abgegrenzte Verantwortlichkeit haben. Und dies bedingt unter anderem, dass die Benutzerschnittstelle nicht mit anderem Zeugs in einen Topf geworfen wird. Folglich muss es für den Entwickler leicht sein, die Benutzerschnittstelle in Form von Komponenten zu implementieren. Mit WinForms war und ist das auch kein Problem. Die Komponenten für die Benutzerschnittstelle sind Library-Projekte wie bei allen anderen Komponenten auch. In Library-Pojekten kann eine WinForms Form mit Visual Studio ganz leicht hinzugefügt werden. Wieso geht das nicht mit WPF?

Für sachdienliche Hinweise bin ich dankbar. Wie lege ich WPF Forms in DLL Projekten an?

Kick it on dotnet-kicks.de