Montag, 23. Mai 2011

Drei Zwecke fürs Refactoring

Refactoring ist zu einer festen Vokabel in der Branche geworden, würde ich sagen. Ohne Refactoring geht es in älteren größeren Projekten einfach nicht. Deshalb hat Refactoring, so scheint mir, ein sehr pauschal gutes Image. Refactoring sollte man können und tun. Bei TDD ist es sogar in der Definition: red-green-refactor.

Mir scheint jedoch, dass wir gut daran täten, zu differenzieren. Ist Refactoring immer gleich? (Womit ich nicht “Extract Method” mit “Extract Interface” vergleichen will.) Hat Refactoring immer denselben Zweck? Zweck ist ja nicht, die Umstrukturierung von Code unter Beibehaltung der Funktionalität. Das ist nur, was passiert.

Ich glaube, es gibt mindestens drei unterschiedliche Zwecke oder Ziele für Refactoring. Jeder hat mit innerer Codequalität vor dem Hintergrund des aktuellen Problemverständnisses zu tun. Innere Qualität existiert nämlich nicht absolut, so denke ich, sondern nur im Verhältnis zu einer Vorstellung davon, was eigentlich das Kern der Anforderungen an eine Software ist und wie eine Lösung grundsätzlich aussehen sollte.

  • Qualität steigern #1: Wenn von Refactoring die Rede ist, dann ist meist Refactoring zur Verbesserung der inneren Qualität gemeint. Sie stehen vor einem Brownfield und wollen daraus – zumindest in Teilen – eine blühende Wiese machen. Den Spaghetticode entzerren. Die technische Schuldenlast abtragen. Darum geht es bei legacy code. Die innere Qualität ist schlecht und bevor man auch nur daran denken kann, neue Funktionalität hinzuzufügen, müssen Sie erstmal Grund reinbringen.
    Beispiel: Die 10.000 Zeilen Klasse, die Sie zerlegen, um sie besser zu verstehen und dann zu erweitern.
  • Qualität beibehalten #2: Refactoring lässt sich nicht vermeiden, auch wenn die innere Qualität schon hoch ist. Denn neue Anforderungen mögen eine andere Struktur des Code erfordern. Also müssen Sie auch Refactoring betreiben, um eine hohe Qualität zu erhalten. Das finde ich wert es zu unterscheiden von Refactoring-Zweck #1.
    Beispiel: Das Refactoring nach den TDD red-green-Schritten.
  • Qualität transformieren #3: Schließlich gibt es noch einen weiteren Refactoring-Zweck, der nicht unbedingt mit neuen Anforderungen zu tun hat. Bei #1 geht es darum, Code für die Umsetzung von Anforderungen überhaupt fit zu machen; bei #2 geht es darum, fitten Code fit zu halten im Lichte neuer Anforderungen. Aber bei #3 ist der Code fit (hohe innere Qualität), keine neuen Anforderungen liegen an – und doch treibt Sie etwas zum Refactoring – und zwar eine neue Sichtweise auf Problem und Code. Domain Driven Design nennt das refactoring to deeper insight. Die tiefere Einsicht kann darin bestehen, dass Lösungsbestandteile umgewichtet werden oder Sie erkennen, dass zwischen manchen Bestandteilen eine engere Beziehung besteht, als zunächst gedacht. Das sollte sich dann auch in der Struktur des Codes ausdrücken.
    Wie gesagt: Anlass für ein solches Refactoring ist keine Schwierigkeit, Änderungen anzubringen, sondern die Erkenntnis, das Struktur und Problem nicht mehr optimal zueinander passen. Durch ein refactoring to deeper insight erhöht sich die Verständlichkeit von Code.
    Beispiel: Sie ziehen die Funktion BonitätPrüfen() aus einer Kundenklasse raus in eine eigene Klasse Bonitätsprüfer, nicht weil sie schwieriger zu ändern wäre in der Kundenklasse oder darin zu unschönen Abhängigkeiten führen würde, sondern weil sich herausstellt, dass die Bonitätsprüfung ein zentraler Bestandteil der Anwendung ist, der verdient, in einer eigenen Klasse oder gar Komponente repräsentiert zu sein.

Mit dieser Unterteilung von Refactoring nach Zwecken, können wir nun besser in unseren Gesprächen unterscheiden, worüber wir sprechen. Wenn zum Beispiel ein Kunde hört, wir würden Zeit in Refactoring stecken und zuckt, weil er denkt, die innere Qualität müsse wohl schlecht sein, dann können wir schneller das Missverständnis aufdecken. Denn wo er an #1 gedacht hat, haben wir in Wirklichkeit über #3 gesprochen.

Oder wir können uns Maximen formulieren:

  • Vermeide Refactoring #1 von vornherein dadurch, dass du hohe innere Qualität produzierst mittels Flow-Design und/oder TDD.
  • Denke an Refactoring #2 im Zuge jeder Änderung an vorhandener hoher innerer Qualität.
  • Sei offen für tiefere Einsichten, die du im Code durch Refactoring #3 manifestierst, damit der Code noch besser verständlich wird.

Mir hat diese Unterscheidung jedenfalls in der letzten Zeit geholfen.

In diesem Sinne: happy refactoring!

Spendieren Sie mir doch einen Kaffee, wenn Ihnen dieser Artikel gefallen hat…

Sonntag, 22. Mai 2011

AppKata – Enter the next level

imageWer schon alle CodeKata Übungen durch hat – Kata Potter, Bowling, LOC, Poker, Fizz Buzz und wie sie alle heißen –, der kann jetzt eine neue Herausforderung annehmen: eine AppKata.

AppKatas – kurz für Application Kata – sind Übungsaufgaben wie CodeKatas, nur umfangreicher. CodeKatas stellen vor allem überschaubare algorithmische Probleme. Da ist typischerweise ein kleiner API zu entwickeln (wenn er nicht schon vorgegeben ist wie z.B. bei der Alpha-End Kata) und mit Code zu unterfüttern. Die Lösung zu finden ist zwar manchmal knifflig, allemal wenn man sie dann z.B. strikt mit TDD implementieren will – doch am Ende ist eben auch nicht mehr dran an einer CodeKata.

Das ist auf der einen Seite gut, weil CodeKatas deshalb recht zügig zu lösen sind. Mit 1-2 Stunden ist man dabei. Das ist überschaubarer Aufwand, der (hoffentlich) mit einer lauffähigen Lösung belohnt wird.

Auf der anderen Seite ist das aber beschränkend. Mehr als etwas Codieren und Testen kann man kaum üben. Wer andere Skills verbessern will, hat an CodeKatas nur magere Kost. Die mit Komponentenorientierung umzusetzen, wäre künstlich. Dafür einen automatischen Build aufzusetzen, wäre mit Kanonen auf Spatzen schießen. Architektur oder Modellierung – wozu?

Das sind aber auch alles Fähigkeiten, die man verbessern kann. Warum immer nur automatisiertes Testen üben? Im Team eine ganze Anwendung entwickeln: das ist eine Herausforderung, die den ganzen Entwickler braucht.

Aus diesem Grund haben Stefan Lieser und ich nun beschlossen, aus unserem Übungsfundus der Clean Code Developer School zu schöpfen und einige der Aufgaben als AppKatas zu veröffentlichen. Das sind immer noch recht überschaubare Übungen, bei denen es nicht um spezielle Technologien geht, sondern die Herangehensweise. Doch es sind Aufgaben, die zu “echten Anwendungen” führen. Kleinen Anwendungen, aber eben ganzen Anwendungen mit Frontend und Ressourcenzugriff usw.

Für die wird man länger brauchen als für CodeKatas, aber das macht nichts. Sie müssen ja nicht in einem Rutsch gelöst werden. Oder man konzentriert sich nur auf einen Aspekt; zum Beispiel könnte man die Modellierung herausgreifen und auf das Codieren verzichten. Je nach Zeit und Anspruch.

Für die AppKatas haben wir eine eigene Seite eingerichtet auf unserer Clean Code Advisors Homepage. Dort werden in den nächsten Wochen in kleinen Happen AppKatas erscheinen. Auch das gehört zur AppKata: die Präsentation in Iterationen. Die AppKata Aufgabe wird nie “in einem Stück” dargestellt, sondern in mehreren Blöcken, die aufeinander aufbauen. Mit jedem Block kommen Anforderungen hinzu.

Wer es also richtig ernst meint mit dem Üben, der liest immer nur die Anforderungen einer Iteration, implementiert sie und schreitet dann erst zu den Anforderungen der nächsten Iteration weiter. So stellt man die Evolvierbarkeit seines Code wirklich auf die Probe.

Die AppKatas sind für größtmögliche Allgemeingültigkeit formuliert. Wir bemühen uns, keine Plattformabhängigkeiten zu haben. Jeder soll sich mit seiner Programmiersprache daran üben können, von Ruby über C# und Java bis zu Haskell.

Und die AppKatas werden wohl meist in Englisch formuliert sein, um auch international zum Üben anregen zu können. Aber das sollte für niemanden in DACH eine Hürde darstellen – oder?

Also, auf geht´s! Wer macht mit? CodeKatas sind für Anfänger; AppKatas sind für Profis ;-) Da ist der ganze Entwickler, die ganze Entwicklerin gefragt – oder auch das ganze Coding Dojo Team. Hier gehts los…

Spendieren Sie mir doch einen Kaffee, wenn Ihnen dieser Artikel gefallen hat…