Ich habe meine "Weiterbildungs-Trilogie" abgeschlossen:
1) Martin Fowler: Refactoring -- Improving the Design of Existing Code
2) Eric Freeman & Elisabeth Robson: Head First Design Patterns -- A brain friendly guide
3) Roy Osherove: The Art of Unit Testing
Alle drei Bücher sind sehr empfehlenswert, wenn auch stilistisch ziemlich unterschiedlich.
Refactoring
Das erste Buch enthält eine Einführung zum Thema und einige vertiefende abschließende Kapitel, der Hauptteil ist aber ein Katalog von Refactoring-Techniken mit Zweck, Anleitung und möglichen Problemen verschiedener Refactorings (z.B. Methode umbenennen, Felder (nachträglich) kapseln, usw.) Klingt erstmal wenig spektakulär, ich fand es aber sehr erhellend, vor allem im Hinblick auf "was kann schon schiefgehen, wenn ich hier eine Kleinigkeit ändere?"
Der Grundgedanke von Refactoring ist aber ein ganz konkreter: Design Patterns sind schön und gut, aber die Design-Entscheidungen, die zu Beginn des Projekts getroffen wurden könnten sich (nach Hunderten von Änderungswünschen) als nicht mehr so gut erweisen. Refactorings bieten eine Möglichkeit, Design Patterns nachträglich zu implementieren, und das (im Idealfall) ohne das Verhalten der Software zu ändern.
Design Patterns
Das zweite Buch gibt etliche Beispiele für clevere Muster, mit denen häufige Design-Probleme gelöst und künftig vermieden werden können. Der eine oder andere mag sagen "ist doch eigentlich nur saubere objektorientierte Programmierung", aber trotzdem schadet es ja nicht, sich die sauberen Lösungen von anderen mal genauer anzuschauen.
Die eigentlich spannende Frage ist nun: wie viel Zeit soll bitte in die Design-Phase einfliesen, damit ich alle Patterns erkenne und einbinde, die ich benötige? Darüber schweigt das Buch ein wenig -- aber in Verbindung mit Refactoring ist die Lösung klar: so viel Design, wie nötig, um die aktuelle Aufgabe zu lösen. Falls Design-Entscheidungen nicht optimal für künftige Erweiterungen sind lässt sich das mit Refactoring nachträglich abändern. Groovy shit!
Eine wichtiger Hinweis: Die Heads-First-Reihe bietet keine Nachschlagewerke, sondern Lehrbücher. Es gibt einprägsame Stories, manche witzige (oder weniger witzige) Unterbrechung, viele Wiederholungen und Aufgaben für Zwischendurch. Zum einmal lesen und lernen ist das super, als Nachschlagewerk nicht so.
Unit Testing
Woher weiß ich nun bei längeren Refactoring-Orgien, die das ganze Design umwälzen, dass ich keine Bugs einbaue? Die Lösung (die in den anderen Büchern immer wieder betont wird) sind Unit-Tests. Wie man clevere Unit-Tests schreibt, wie man beim Schreiben und Pflegen von Unit-Tests möglichst wirtschaftlich bleibt und welche Tools man einsetzen kann, davon handelt das dritte Buch.
Nicht zu trocken, aber nicht so flippig, wie Heads-First... sehr angenehm zu Lesen und lädt direkt zum "Mitmachen" ein, ohne dauern kleine Hausaufgaben zwischenzuwerfen.
Warum Trilogie?
Warum bezeichne ich das ganze nun als Trilogie, wo doch Autoren und Stil der Bücher völlig verschieden sind? Ganz einfach: um Design Patterns zu implementieren brauchen wir Refactoring-Techniken. Um entspannt zu Refactorn brauchen wir Unit-Tests. Diese drei Themen bilden die wichtigen Grundpfeiler moderner Software-Entwicklung -- und wie ich fürchte werden sie in vielen Unternehmen längst nicht genug eingesetzt.
Aber nun kommt das große Problem: um gute Unit-Tests schreiben zu können brauche ich gute Design Patterns... hüstel. Da beißt sich der Hund in den Schwanz. Wie kommt man nun aus dem Deadlock eines Legacy-Projekts mit nicht mehr zeitgemäßem Design und ohne Unit-Tests raus? Refactoring verbietet sich (!!!) ohne gute Unit-Tests. Unit-Tests lassen sich unter umständen nur schwer einbauen... The Art of Unit-Testing liefert einen Einstieg in die Frage, wo die Unit-Tests für Legacy Code herkommen und verweist ansonsten auf Michael Feathers: Working effectively with legacy code. Das werde ich wohl als vierten Teil meiner Trilogie lesen, aber erstmal brauche ich ein wenig Entspannung von Arbeitsbüchern ;)
- Thomas