Archiv

Posts Tagged ‘Clean Code’

Code mittels NDepend analysieren

9. April 2014 1 Kommentar

Um möglichst schnell in ein komplexeres Projekt einzusteigen hilft einem eine gute Übersicht. Visual Studio bietet je nach Ausgabe eine recht gute Code Analyse. Will man mehr wissen oder ist man an bestimmten Konstellationen im Code interessiert, stösst man aber schnell an Grenzen. Hier benötigt man einmal mehr die Werkzeuge und Ergänzungen von Drittherstellern.

Als ich vor einigen Wochen gebeten wurde mir NDepend anzuschauen kam mir dies sehr gelegen. NDepend ist ein Tool zur statischen Code Analyse für .Net. Damit lässt sich der Code nicht nur auf vorgefertigte Qualitätskriterien überprüfen, sondern man kann auch eigene Abfragen definieren.

 

Download und Installation

Auf NDepend.com kann man die Demo-Version als Zip herunterladen. Die Installation beschränkt sich aufs entpacken der Datei und einem Doppelklick auf die Installationsdatei.

Wenn einem die Möglichkeiten von NDepend gefallen bekommt man eine entsprechende Lizenz ab 299€. Leider gibt es keine GUI-basierende Möglichkeit um den Lizenzschlüssel einzugeben. Die Lizenzdatei muss man in den entpackten Ordner kopieren bevor man Visual Studio startet. Sonst wird nach Ablauf der Evaluationsperiode NDepend beim nächsten Start von Visual Studio deinstalliert.

Läuft NDepend genügt es das gewünschte Projekt in Visual Studio zu öffnen und über den Menüpunkt “NDepend” die Analyse zu starten. Dieser Vorgang ist zwar recht schnell, kann je nach Projektgrösse aber dennoch einige Minuten dauern.

 

HTML-Report

Das erste was einem als Resultat begegnet ist der HTML-Report. Dieser enthält die wichtigsten Punkte und soll als Zusammenfassung fürs Management dienen. Leider ist die Funktionalität äusserst beschränkt und damit einzig als Druckversion für die Gesamtsicht zu gebrauchen.

NDepend Report

 

Visual NDepend

Mit Visual NDepend hat man ein deutlich besseres Werkzeug zur Verfügung. Hier kann man die Grafiken genauer anschauen und auch einzelne Klassen auf der TreeMap finden. Klickt man auf Klassen- oder Methodennamen öffnet sich Visual Studio und zeigt einem die passende Stelle an.

Da alle Funktionen nur hier schön zusammengefasst werden dürften die meisten Benutzer vor allem mit Visual NDepend arbeiten. Man hat zwar immer noch den Wechsel zwischen Visual Studio und Visual NDepend, dafür kommt man aber sehr schnell zu den gewünschten Informationen.

Visual NDepend

 

Integration in Visual Studio

Die Integration in Visual Studio ist sehr gut und man kann mittels Rechtsklick auf eine Klasse die einzelnen Auswertungen direkt aufrufen. Bei der Gesamtübersicht wurde auf dem Dashbard allerdings nicht alles aus Visual NDepend übernommen. Es ist zwar alles in Untermenüs vorhanden, aber bis man die einzelnen Grafiken findet kann es dauern…

NDepend VS2013

 

Eigene Abfragen

NDepend glänzt vor allem durch die Abfragesprache CQLinq. Damit kann man selber den Code nach eigenen Kriterien durchsuchen (wie mehr als 4 Methoden mit mehr als 3 Parameter und mehr als 10 Attribute pro Klasse). Hat man gewisse Konstellationen entdeckt die häufig zu Problemen führen hilft einem CQLinq beim aufspüren.

Die Dokumentation zu CQLinq ist sehr ausführlich und sollte vor dem Experimentieren konsultiert werden. Die Hilfestellung bei Fehlern im Editor ist nicht gerade optimal und da die Abfragen immer gleich ausgeführt werden wird man sehr schnell mit Fehlermeldungen eingedeckt.

NDepend Query Editor

 

Verbesserungspotential

Die Inkonsistenzen der 3 Ansichten (HTML-Report, Visual NDepend und Visual Studio) sind nicht gerade Benutzerfreundlich. Hat man sich einmal daran gewöhnt kann man damit arbeiten. Allerdings ist es schade wenn man viel Zeit mit der Suche nach einer bestimmten Auswertung verliert nur weil sich diese in einem anderen Tool befindet.

Mit einer verständlicheren Kategorisierung der Fehler könnten die Reports auch dem Fachdienst bei der Beurteilung helfen. Code Climate schafft dies mit der Benotung A bis F für einzelne Klassen. Während ein A sehr gut ist gilt ein F als dringend zu verbessern. Zudem wird schön aufgezeigt wie sich der Code über die Zeit entwickelt, was einen zusätzlichen Motivationsschub gibt. Leider fehlen solche einfachen Werte bei NDepend, auch wenn Ansätze zum Verfolgen der Veränderungen vorhanden sind.

 

Fazit

NDepend ist ein tolles Tool für Entwickler die mehr über ihren Code wissen wollen. Um die Möglichkeiten voll auszuschöpfen wird man aber einiges an Zeit investieren müssen um selber CQLinq Abfragen zu erstellen.

Ausserhalb der Entwicklung sind die Einsatzmöglichkeiten von NDepend allerdings sehr beschränkt. Die Probleme bei der Benutzerführung und die Inkonsistenzen sind wie die Reports wenig hilfreich um mit dem Fachdienst über Qualitätsverbesserungen zu diskutieren.

Schlagworte: , ,

Buch-Rezension zu “Code Complete 2nd Edition”

4. März 2014 Kommentare aus

Code Complete 2nd editionCode Complete – A Practical Handbook of Software Construction (2nd edition)” von Steve McConnell gilt als Standardwerk das man unbedingt gelesen haben muss. Es behandelt alle wichtigen Themen der Softwareentwicklung und gewann zahlreiche Preise.

Nach langem fand ich doch noch die Zeit um dieses Buch zu lesen. Allerdings fragte ich mich sehr bald ob die Empfehlungen auf Amazon vom gleichen “Code Complete” handeln. Entgegen der weit verbreiteten Meinung hatte ich kein praktisches Handbuch vor mir, sondern die ausführlichste Auflistungen von Studien die ich je gesehen habe. Nach zahlreichen weiteren Entdeckungen kann ich von diesem Buch nur abraten.

 

Solider 1. Eindruck

Liest man das Inhaltsverzeichnis durch sieht man dass alle wesentlichen Teile der Erstellung von Software in diesem Buch behandelt werden. Wie McConnell im Vorwort schreibt geht es ihm um eine ausgewogene Diskussion und nicht um Hype. Dies tönt vielversprechend und durchs ganze Buch hinweg untermauert er seine Aussagen mit Studien.

Die zahlreichen Diagramme helfen einem beim Verstehen der gerade vorgestellten Ideen und die Checklisten sind ein guter Ausgangspunkt um die gewonnenen Erkenntnisse im eigenen Code umzusetzen.

Versucht man allerdings mit dem Buch zu arbeiten bemerkt man schnell die ersten Probleme.

 

Genauer hingeschaut

Die objektive und ausgewogene Diskussion erreicht McConnell durch das Referenzieren von Studien. Über die ersten Kapitel hinweg erweckt dies einen sehr professionellen Eindruck. Bis man feststellt das McConnell einen Artikel eines gewissen “McConnell, S.” zitiert. Einen eigenen Artikel zu zitieren ist ja kein Problem, doch sollte man auf diesen Punkt hinweisen. Dies wäre besonders wichtig wenn es sich um ein eher kontroverses Thema handelt und der eigene Artikel der einzige Text ist der die eigene These stützt.

Richtig interessant wird es aber erst wenn die einzige Studie zu einem Thema unübersehbar falsch ist. Auf Seite 518 werden die Fehlerarten gemäss der Studie von Boris Beizer von 1990 aufgeführt. Es wurde dabei so genau gearbeitet dass die Prozentwerte auf 2 Nachkommastelen genau ausgewiesen werden. Dies obwohl die Studie nur die Resultate anderer Studien kombinierte und deren Werte mehr als 50% voneinander abweichen. Auf all diese Fehler weist McConnell explizit hin. Seine Schlussfolgerung daraus ist, die Werte mögen so nicht stimmen aber die Richtung ist in Ordnung. Er verwendet diese Werte danach um seinen Punkt zu beweisen – allerdings ohne die Nachkommastellen…

Wenn man so mit Studien arbeitet kann man auch gleich darauf verzichten. Dieses Beispiel ist das offensichtlichste, allerdings gibt es noch zahlreiche weitere Stellen wo die Resultate so lange verdreht werden bis der gewünschten Punkt „bewiesen“ ist.

 

Zu kurz

Obwohl das Buch rund 960 Seiten hat ist es viel zu kurz um die Fülle an Themen auch wirklich zu erklären. Lässt man das Vorwort, den Anhang, die einzelnen Verzeichnisse, die Checklisten und die Zusammenfassungen weg bleiben für jedes der 35 Kapitel nur noch 20 Seiten übrig. Das reicht in der Regel nur um das jeweilige Thema kurz anzuschneiden.

Besonders deutlich wird dies beim Kapitel “Refactoring“. Die Gründe für Refactoring werden von McConnell sehr gut dargelegt, gleiches gilt für mögliche Strategien. Wie man allerdings den eigenen Code umbauen soll bleibt unklar. Zu mehr als 2-3 Sätzen pro Refactoring-Technik reicht der Platz in diesem Kapitel nicht. Der Praxisnutzen ist dementsprechend gering und das Vorgehen für Refactorings erschliesst sich nur den Lesern, die den zu vermittelnden Inhalt bereits kennen. Da könnte man das Kapitel eigentlich gleich ganz weg lassen.

Leider ist dieser Platzmangel nicht auf ein Kapitel beschränkt sondern zieht sich durchs ganze Buch.

 

Wo es gefährlich wird

Der lockere Umgang mit Studien und der zu knappe Platz um ein Thema wirklich zu erklären birgt ein grosses Gefahrenpotential. Dies wird besonders bei den Kapiteln 25 und 26 deutlich, wo das Thema “Code-Tuning” behandelt wird.

Nach einem Hinweis über die Wichtigkeit von Messungen zu Beginn der Optimierung (Baseline) beginnt eine kaum enden wollende Reihe von Mikro-Optimierungen. Ist es schneller eine Schlaufe zum zuweisen der Array-Werte zu verwenden oder sollte man diese einzeln aufschreiben? Soll man bei verschachtelten Schlaufen zuerst über die innere oder über die äussere Schlaufe iterieren?
Zu all diesen Fragestellungen gibt es einen Codeschnipsel und eine Tabelle. Je nach Sprache und Problem variiert die Grösse der Einsparmöglichkeiten oder ist sogar negativ. Es fehlt einzig ein Hinweis wie diese Werte zustande kommen.

Erst nach gut 50 Seiten dieser Mikro-Optimierungen erklärt McConnell wie er diese Werte berechnet hat:

[For the first edition] I ran most of the tests in this chapter 10‘000 to 50‘000 times to get meaningful, measurable results. For this edition I had to run most tests 1 million to 100 million times. When you have to run a test 100 million times to get measurable results, you have to ask whether anyone will ever notice the impact in a real program.

Diese Fragestellung hätte McConnell zu Beginn des Kapitels aufwerfen müssen. So allerdings erklärt man den Lesern erst ausführlich wie gross die Unterschiede zwischen den einzelnen Varianten sind obwohl diese in der Realität keine Bedeutung haben.
In der Folge davon darf man in unzähligen Projekten grosse Diskussionen über die Reihenfolge von Schlaufen führen. Denn schliesslich hat McConnell ja gezeigt das dieser Ansatz 73% schneller ist…

 

Alternativen

Wer seine Lesezeit sinnvoller verwenden will sollte sich diese 3 Bücher anschauen:

Lässt man die Anhänge weg sind diese Bücher zusammen auch rund 960 Seiten lang. Allerdings werden hier die jeweiligen Themen praxisnah und verständlich beschrieben.

 

Fazit

Auf den ersten Blick ist “Code Complete” ein sehr gutes Buch mit zahlreichen interessanten Ideen. Betrachtet man es genauer sieht man sehr bald die vielen Unstimmigkeiten. Aus einer objektiven Darstellung wird so ein zurechtrücken von Studien und durch die vielen angeschnittenen Themen fehlt der Platz um einen wirklichen Praxisnutzen zu vermitteln.

Für Einsteiger ist dieses Buch dadurch nicht geeignet und durch die realitätsfremden Mikro-Optimierungen sogar gefährlich. Und wer sich mit der Thematik bereits auskennt wird kaum etwas Neues finden. Statt “Code Complete” liest man besser die 3 alternativen Bücher, da hat man am Ende auch etwas mit Praxisbezug gelernt.

 

Zum Buch

Code Complete – A Practical Handbook of Software Construction (2nd edition)” von Steve McConnell, 2004 Microsoft Press, ISBN 978-0-7356-1967-8, 960 Seiten, Englisch

 

Schlagworte: , ,

Buch-Rezension zu “The Art of Unit Testing (2nd Edition)”

27. November 2013 2 Kommentare

The Art of UnitTesting 2nd editionSeit Ende letzter Woche gibt es mit “The Art of Unit Testing, Second Edition” eine neue Ausgabe meines favorisierten TDD-Buches. Die erste Ausgabe erschien 2009 und beeinflusste mein Verständnis von Test-Driven Development nachhaltig.

Ich war einerseits gespannt auf die neue Ausgabe und andererseits auch ein wenig unentschlossen ob es wirklich eine neue Ausgabe benötigt. Konnte die neue Ausgabe die kleineren Mankos der 1. Ausgabe wirklich beheben? Oder gibt es am Ende ein ganz anderes Buch das nur den gleichen Namen trägt?

 

Aufbau beibehalten, Inhalt überarbeitet

Die Kapitelstruktur der 2. Ausgabe unterscheidet sich nur minimal von der 1. Ausgabe. Der ehemalige Anhang A “Design and testability” ist nun ein “richtiges” Kapitel und Mock-Frameworks werden in einem zusätzlichen Kapitel noch eingehender angeschaut. Die übrigen Kapitel blieben alle erhalten und wer sich nur am Inhaltsverzeichnis orientiert wird diese 2. Ausgabe wohl schnell wieder weglegen.

Die grossen Neuerungen finden sich in den Kapitel selber. Diese wurden komplett überarbeitet und liefern nun eine noch bessere Erklärung wieso man seine Unit Tests auf diese Art organisieren und strukturieren soll. Die Beispiele sind nun so gut dass man dieses Buch auch problemlos einem Anfänger geben kann. Roy Osherove führte zwischen den 2 Büchern zahlreiche TDD-Kurse durch und hat seine dabei gewonnenen Erkenntnisse in die 2. Ausgabe einfliessen lassen. Dadurch wurde auch hinsichtlich der Praxistauglichkeit nochmal ein Schritt nach vorne gemacht, was sich vor allem an den viel klareren Namensregeln zeigt.

Wenn man die erste Ausgabe kennt und täglich mit Unit Tests arbeitet wird man fast nur bei den Mock-Frameworks neue Erkenntnisse bekommen. Die aktuelle Liste lieferte einem eine gute Übersicht und kann einem auch helfen sich gegen ein bestimmtes Framework zu entscheiden:

MSFakes might be free and included with Visual Studio, but it will cost you a lot of money down the line in developer hours, fixing and trying to understand your tests.

Wer seine erste Ausgabe nicht nur als Staubfänger nutzt sollte sich die 2. Ausgabe zulegen. Ob man das Buch als Nachschlagewerk, zum Auffrischen seiner Unit Testing Kenntnisse oder für neue Teammitglieder braucht – die überarbeiteten Kapitel sind einfacher zu verstehen und näher an der Praxis.

 

Fazit

Mit der 2. Ausgabe konnte Roy Osherove die hohen Erwartungen übertreffen und ein noch besseres Buch über Unit Testing liefern. Die darin beschriebenen Vorgehensweisen helfen in der Praxis die Unit Tests im Griff zu behalten und eine Struktur hinein zu bringen. Wenn man die erste Ausgabe besitzt und damit noch arbeitet lohnt sich auch der Kauf der 2. Ausgabe.

 

Zum Buch

The Art of Unit Testing, Second Edition” von Roy Osherove, November 2013 Manning, ISBN 978-1-6172-9089-3, 296 Seiten, Englisch

 

Schlagworte: , , ,

Von fachlichen und technischen Daten

31. Juli 2013 Kommentare aus

In einer Geschäftsanwendung werden vor allem fachliche Daten bearbeitet. Daneben gibt es aber eine ganze Reihe von technischen Daten (wie einer ID oder einem Erstelldatum). Diese beiden Arten von Daten können problemlos nebeneinander abgelegt werden. Sobald man allerdings beginnt die Grenzen zu verwischen fangen die Probleme an.

Bis sich die Auswirkungen dieser Vermischung bemerkbar machen kann man sich meist nicht mehr an die dazugehörigen Entscheidungen erinnern. So beginnt ein mühsames Suchen nach den Ursachen von teils äusserst seltsamen Fehlern.

Ich will gar nicht zusammenrechnen wie viele Stunden ich so verloren habe. Dabei waren es zu Beginn jeweils ganz kleine Entscheidungen die am Ende zu solchen Problemen führten. Wie klein die sein können soll das nachfolgende fiktive Beispiel rund um Auftragsformulare zeigen.

 

Wenn aus technischen Daten fachliche werden…

Meist beginnt alles mit einer kleinen zusätzlichen Anforderung. Neu soll beispielsweise das Eingangsdatum eines Formulars geführt werden. Man kann nun ein zusätzliches Feld “Eingang” anlegen oder den Wert ins Feld “Erstellt” hineinschreiben. Das ist ja für die Anwendung das gleiche, da alle Formulare beim Eintreffen erfasst werden.

Allerdings wird das Feld “Erstellt” durch die Anwendung hinweg immer als technisches Feld betrachtet das man weder auf der Oberfläche anzeigt noch irgendwie sonst verwendet. Damit ist es nun vorbei. Für das Objekt “Formular” wird das Feld “Erstellt” nicht nur angezeigt sondern auch noch gleich umbenannt – allerdings nur auf der Oberfläche. Und in den Reports. Und im Export. Und bei allen anderen zukünftigen Verwendungen dieses Objekts.

 

… und dies zu Problemen führt

Die Sonderregelung für “Formular” ist zu diesem Zeitpunkt schon aufwändig aber noch kein Problem. Dazu braucht es meist noch eine kleine Veränderung der Geschäftsabläufe, wie einer externen Erfassung der Formulare.

Um diese externe Erfassung zu ermöglichen kommt dann oft eine Excel-Liste als Transfermethode zum Einsatz. So müssen die externen Sachbearbeiter nichts Neues lernen und im Zielsystem wird eine kleine Importfunktion hinzugefügt. Soweit ist dies ebenfalls noch kein Problem. Doch was soll nun ins Feld “Erstellt” geschrieben werden? Das Datum an dem die Daten importiert wurden oder das Eingangsdatum?

Aus fachlicher Sicht muss das Eingangsdatum gesetzt werden, da sich zwischen dem Eingang und dem Import Preise verändert oder Fristen abgelaufen sein könnten. Aus technischer Sicht wird das Formular mit dem Import erstellt.

Das Problem ergibt sich sobald beide Sichten “ihr” Datum benötigen. Das technische Erstelldatum könnte beispielsweise für einen Report zur internen Kostenverrechnung dienen. Wird dieser Report nach Eingang aber vor dem Import der Formulare ausgeführt stimmen die Werte nach dem Import nicht mehr mit dem Datenbestand in der Applikation überein. Die importierten Formulare fehlen im Report, werden daher nicht verrechnet und Ende Jahr gilt es zu klären woher die Differenz kommt.

 

Ursachen

Bei den Fällen die mir bekannt sind war die Ursache oft eine verfrühte Optimierung oder der krampfhafte Versuch Diskplatz zu sparen. Weder der zusätzliche Speicherplatz noch der Aufwand ein Feld mehr anzulegen hätte man bemerkt. Im Gegensatz zu all dem Aufwand zum Aufspüren der fehlerhaften Auswertungen.

Bitte beachten: DRY (Don’t repeat yourself) gilt nur wenn es sich wirklich um die gleichen Dinge handelt. Andernfalls ist dies keine Repetition sondern erfüllt einen anderen (unabhängigen) Zweck.

 

Wie verhindern?

Im obigen Beispiel hätte man spätestens als die Importfunktion erstellt wurde die Datenfelder trennen müssen. Allerdings denkt in so einem Moment niemand an solche Zusatzaufgaben. Und nur um Daten genauer abzulegen will niemand all die Oberflächen und Reports anpassen.

Daher bin ich mittlerweile der Meinung dass bei den ersten Anzeichen einer fachlichen Verwendung der technischen Daten die Alarmglocken läuten müssen. Fängt man an bei einzelnen Objekten technische Felder einzublenden ist dies ein deutliches Zeichen das hier ein fachliches Feld fehlt. Der Aufwand dies jetzt gleich sauber zu lösen ist geringer als wenn man wartet bis dieses Feld überall verwendet wird. Und fehlt doch gerade die Zeit kann man immer einen entsprechenden Task eröffnen und im nächsten Sprint (mit zusätzlichen Informationen) beheben.

Dies gilt übrigens im gleichen Masse für fachliche Felder die technisch genutzt werden, auch wenn dieser Fall wohl weniger oft vorkommt.

 

Fazit

Das Single Responsibility Principle (SRP) gilt nicht nur für Klassen und Methoden, sondern auch für Daten. Bevor man für eine kleine Einsparung bei der Datenmenge anfängt Felder mehrmals zu verwenden sollte man sich über die möglichen Konsequenzen bewusst werden und darauf verzichten. Angesichts der aufwändigen Fehlersuche bezweifle ich das durch ein “eingespartes” Feld wirklich Kosten gespart werden können.

Schlagworte: , ,

Buch-Rezension zu “Working Effectively with Legacy Code”

30. Mai 2013 Kommentare aus

Legacy Code Viele Bücher zeigen wie man mittels TDD sauberen Code schreiben kann. Michael Feathers geht in “Working Effectively with Legacy Code” einen anderen Weg. Er zeigt wie man aus Legacy Code Schritt für Schritt und mit viel Arbeit eine saubere Codebasis schaffen kann.

Dieser Weg ist alles andere als leicht, startet dafür aber dort wo wohl die meisten Software-Projekte sind: Bei einer grossen Menge Code mit nur wenigen (oder gar keinen) Tests und der dennoch geschäftskritische Funktionen erfüllt. Wie erhält man dessen Funktionalität und schafft es gleichzeitig flexibel auf neue Anforderungen zu reagieren?

 

Schritt für Schritt

Wichtig ist das man nicht gleich zu Beginn alles hinwirft. Nur weil der Code noch über keinen einzigen Test verfügt bedeutet dies nicht dass dies so bleiben muss. Im Buch findet man für sehr viele Situationen Tipps und Tricks um mit dem Testen zu beginnen.

Allerdings kann man nicht von einem Extrem in andere springen. Wo noch keine Tests vorhanden sind gleich mit TDD alles machen zu wollen wird sehr schnell scheitern. Besser ist es mit wohlüberlegten und gezielten Tests zu beginnen. Vor der geplanten Änderung erst einmal den Code anschauen und mit Tests auf einer höheren Ebene (wie Integrations- oder Akzeptanztests) beginnen. Oft braucht es auch Mut erst einmal ein Loch aufzureissen um überhaupt einen Test scheiben zu können. Denn wenn man vor dem ändern von Code erst einen Test haben will und für diesen Test erst eine Anpassung am Code braucht steht man vor einem Henne-Ei Problem.

Soll sich die Situation verbessern muss man bereit seit für eine gewisse Zeit mit Code zu leben der nicht allen OO-Regeln folgt. Zusätzliche Konstruktoren nur um Abhängigkeiten zu übergeben sind oft nötig bis dies „korrekt“ gelöst werden kann. Bleibt man dran und geht konsequent den eingeschlagenen Weg kann man auch das grösste Gestrüpp entwirren – dies geschieht aber nicht über Nacht.

 

Einstellung ändern

Aber was ist eigentlich Legacy Code genau und warum ist dies etwas Schlechtes? Feathers hat in seinem Buch zwei Definitionen, von denen man in der Regel nur die weniger freundlich formulierte in Erinnerung behält:

Legacy Code is Code Without Tests

In dem Sinne liegt es bei jedem einzelnen Entwickler aufzuhören vorneweg Legacy Code zu schreiben und sich über die Qualität und Testbarkeit seines Codes Gedanken zu machen. Andernfalls sind all die im Buch aufgezeigten Ansätze für nichts und man ist in kurzer Zeit wieder da wo man begonnen hat.

Was Michael Feathers in seinem Buch leider nicht anspricht ist wie man sein Team von der Notwendigkeit von wartbarem Code überzeugen kann. Genau dies aber dürfte in vielen Projekten wohl das grösste Hindernis sein.

 

Characterization Tests

Von all den verschiedenen Ansätzen die in diesem Buch vorgestellt werden fand ich die Characterization Tests am hilfreichsten. Bei diesen Tests fängt man nicht wie bei TDD mit dem gewünschten Verhalten an und folgt dem Red-Green-Refactor Mantra. Stattdessen beginnt man den Test in dem man beim Assert-Aufruf das Resultat der Methode mit dem Default-Wert des entsprechenden Datentyps vergleicht. Der Test wird in den meisten Fällen fehlschlagen und die Fehlermeldung liefert einem den korrekten Wert. Dieser setzt man dann im Assert-Aufruf ein und hat so einen erfolgreich bestandenen Test.

Ohne den Code anzupassen kann man so recht schnell die einzelnen Eigenschaften einer Methode oder einer ganzen Klasse durch Tests fixieren. Dieses Korsett an Tests dient einem nach dem Refactoring zu verifizieren das die Verbesserungen das Verhalten des Codes nicht verändert haben.

Um Legacy Code mit Tests zu versehen macht man also genau das was bei TDD verpönt ist: Den Test so zu schreiben das der aktuelle Code diesen besteht ohne sich Gedanken über die wirklichen Anforderungen zu machen. Aber genau dies macht diese Art von Tests für mich so praxisrelevant. Hat man Legacy Code muss man auf diesen eingehen und eine Lösung finden die den aktuellen Code beschreibt. Hat man einmal so viele Tests dass man wirklich weiss was der Code macht gilt es wieder den Schalter umzulegen und zu prüfen ob dies auch wirklich korrekt ist. Bis es so weit ist muss man die liebgewordenen Regeln aber auch einmal zurückstellen können.

 

Weiterführende Bücher

Nach dem der Code mit Tests versehen ist geht es ans Aufräumen. Dazu verweist Feathers oft auf Martin Fowlers “Refactoring“. Das Standardwerk zu diesem Thema sollte man kennen, da man ansonsten den Ausführungen kaum folgen kann.

Wer mittels Refactoring grössere Ziele verfolgt sollte auch einen Blick auf “Refactoring to Patterns” von Joshua Kerievsky werfen. Dies baut ebenfalls auf Fowlers Buch auf und erklärt wie man mit einer Kombination von Refactorings grössere Strukturverbesserungen erreichen kann.

 

Fazit

Michael Feathers zeigt einem in diesem Buch wie man von einer durchschnittlichen Codebasis zu einer kommt die dank Tests auf geänderte Anforderungen reagieren kann. Der Weg dorthin ist aber nicht zu unterschätzen und man muss auch einmal bereit sein eine gewisse Unordnung zu akzeptieren. Will man sich darauf einlassen liefert einem dieses Buch viele wertvolle Tipps.

 

Zum Buch

Working Effectively with Legacy Code” von Michael Feathers, 2004 Prentice Hall, ISBN: 978-0-1311-7705-5, 434 Seiten, Englisch

Schlagworte: , ,

Buch-Rezension zu “Domain-Driven Design”

3. Februar 2013 1 Kommentar

Domain-Driven DesignWenn man sich mit Behavior Driven Development (BDD) und dem Schreiben von Akzeptanztests beschäftigt stösst man immer wieder auf ein Buch:
Domain-Driven Design: Tackling Complexity in the Heart of Software” von Eric Evans.

Dieses Buch gilt weit herum als Standardwerk das man unbedingt kennen muss. Beim Lesen merkt man schnell das Evans sehr viel Erfahrung hat und weiss wovon er schreibt. Leider macht er dies so ausführlich dass man kaum vorwärts kommt. “Man müsse die Informationen herausschürfen” ist eine Bemerkung über dieses Buch die man beim Lesen im Hinterkopf behalten sollte.

 

Kernpunkte

Von all den Themen die Evans behandelt stechen für mich diese Punkte besonders hervor:

Mit Hilfe einer Ubiquitous Language (einer einzigen gemeinsamen Sprache) sollen alle am Projekt beteiligten Personen kommunizieren. Dadurch das alle die gleichen Begriffe benutzen können Missverständnisse und Übersetzungsprobleme (im Sinne von Fachspezifisch zu Technisch) früh erkannt werden oder entfallen ganz. Auch ist es für Entwickler einfacher sich an die Spezifikationen zu halten wenn die Objekte im Code gleich heissen wie in den Anforderungen und den Testszenarios.

Bei Refactoring denkt man meistens an einen technischen Vorgang um Code besser zu strukturieren. Neben diesem technischen Aspekt gibt es aber auch einen fachlichen. Evens zeigt bei „Refactoring Toward Deeper Insight“ auf wie man nach und nach das Domänenmodell um neue Erkenntnisse verfeinern kann.

Entwickelt man nach Model Driven Design darf das Modell nicht in einem Vakuum erstellt werden. Ist dieses Modell technisch nicht umsetzbar wird in der Entwicklung gezwungenermassen eine Lösung gefunden die davon abweicht. Damit verliert man alle Vorteile und muss ständig zwischen mehreren Modellen hin und her wechseln. Neben höheren Kosten leidet dabei auch die Kommunikation.

Bounded Context: Das eigene Domänenmodell kann noch so gut sein, wenn man es nicht abgrenzt fliessen die unterschiedlichen Konzepte der Umsysteme hinein. Evens zeigt eine ganze Reihe von Ansätzen um dies zu verhindern (wie das Pattern “Anticorruption Layer”).

Software-Entwicklung ist mehr als das Schreiben von Code. Es geht um das Lösen von Problemen. Damit man die passende Lösung finden kann ist eine Zusammenarbeit mit allen beteiligten Parteien nötigt.

 

Kritik

Die gleichen Namen und Bezeichnungen zu verwenden ist ein grosser Schritt in die richtige Richtung. Nur ist es damit nicht getan. Mir fehlt wie man auch zu einer gemeinsamen Bedeutung kommt und überhaupt die Wiedersprüche aufdecken kann. (Wenn alle von Autos sprechen, wie merkt man das der eine einen Golf meint und der anderen einen Ferrari?)

Die ersten beiden Teile sind sehr schwerfällig geschrieben. Immer wieder springt Evans von einer Idee zur nächsten und wieder holt dieses hin und her mehrmals. Würde dies aus unterschiedlichen Perspektiven geschehen wäre dies ein Plus fürs Buch. Leider sucht man die ganze Zeit nach den Unterschieden zum bereits behandelten und findet meist keine. Dies bremst den Lesefluss und schlägt auf die Motivation.

Anstelle der vielen Wiederholungen wären Beispiele zur technischen Umsetzung hilfreich. Statt so viel über Code zu sprechen hätte Evens diesen zeigen können – dies ginge schneller und hätte einen Praxisnutzen. So bleibt zu viel eine schöne Idee ohne Hinweis auf deren Umsetzung.

 

Alternative

Abel Avram und Floyd Marinescu sahen ebenfalls einige Verbesserungsmöglichkeiten und schrieben 2006 das Mini-Book “Domain Driven Design Quickly“. Auf rund 100 Seiten gibt es all die Konzepte aus dem Buch von Evans, ein Interview mit ihm und es hat noch Platz für Ergänzungen aus “Applying DDD” von Jimmy Nilsson.

Wer ins Thema DDD einsteigen will sollte sich erst einmal das PDF bei InfoQ herunterladen.

 

Fazit

Mit Domain-Driven Design wurden viele wichtige Ideen erstmals in Buchform veröffentlicht. Die darin behandelten Themen sind auch heute noch aktuell und ein Umsetzen der von Evens vorgestellten Ansätze würde so manches aktuelle Problem lösen.

Leider verzettelt sich Evans mit seinen Erklärungen und macht es dem Leser äusserst schwer diese Konzepte zu verstehen. Als Einstiegslektüre ins Thema DDD kann ich dieses Buch daher nicht empfehlen. “Domain Driven Design Quickly” ist dafür die bessere Wahl, da die gleichen Konzepte viel besser auf den Punkt gebracht werden.
Kehrt man nach diesem Umweg zu Evens zurück versteht man seine Ideen viel besser und erkennt dann auch was sonst noch alles für Informationen in diesem Buch stecken.

 

Zum Buch

Domain-Driven Design: Tackling Complexity in the Heart of Software” von Eric Evans, 2003 Addison-Wesley, ISBN 978-0-3211-2521-7, 560 Seiten, Englisch

Kopierten Code finden mit der Code Clone Analyse

14. November 2012 Kommentare aus

Code wird gerne kopiert. Was einem zuerst hilft schnell ähnliche Anforderungen zu erfüllen wird in kurzer Zeit zu einem Problem. Nun ist es nicht mehr damit getan eine Stelle im Code zu korrigieren und der Fehler ist behoben – man muss jetzt immer auch noch alle Kopien korrigieren.

Das Problem dabei ist das man nicht weiss was für Code kopiert wurde und wo der in Modul X aufgetretene Fehler noch alles drin ist. Als Folge davon bleiben die Fehler meist unentdeckt und die Kunden fragen sich wieso sie immer wieder die gleichen Probleme melden müssen.

Seit Visual Studio 2012 hat man beim Aufstöbern dieser Klone eine Hilfe. Die Analysefunktionen wurden um die Funktion Code Clone Detection erweitert. Wie der Name vermuten lässt wird damit kopierter Code aufgespürt.

Führt man diese Auswertung aus muss man sich erst einmal gedulden. Der ganze Code wird in Tokens unterteilt und dann analysiert. Der erstmalige Durchgang ist je nach Codebasis und Geschwindigkeit des Rechners eine gute Gelegenheit für eine ausgedehnte Kaffeepause.

 

Nicht nur 1:1 Kopien

Code der 1:1 kopiert wurde wird von Code Clone als „Exact Match“ gefunden. Damit gibt sich Code Clone aber nicht zufrieden. Kleinere Anpassungen wie umbenannte Variablen werden ebenfalls erkannt und als „Strong Match“ oder als „Medium Match“ klassifiziert.

Richtig interessant wird es bei grösseren Änderungen die als „Weak Match“ eingestuft werden. Hier ist die Chance auf falsch erkannte Klone entsprechend grösser. Dafür findet man hier aber auch die Stellen, die man auf den ersten Blick nicht als Klon erkennen würde:

public void MethodA(string input)
{
    Console.WriteLine("input => ", input);

    string a = input.Trim().ToLower();
    string b = input.Trim().ToLower();
    string c = input.Trim().ToLower();
    string d = input.Trim().ToLower();
    string e = input.Trim().ToLower();

    Write(a);
    Write(a);
    Write(a);
    Write(a);
}

public void MethodB(string input)
{
    string b = input.Trim().ToLower();
    Write(b);
    Write(b);
    Write(b);

    string a = input.Trim().ToLower();
        
    string c = input.Trim().ToLower();
    Console.WriteLine("input => ", input);

    string e = input.Trim().ToLower();
    string d = input.Trim().ToLower();
    Write(b);
}

In diesem Beispiel wurde der gleiche Code anders aufgebaut. Gerade bei solchen Klonen spielt Code Clone seine Stärken aus und erweist sich als äusserst hilfreich.

 

Nebeneffekte

Nutzt man Code Clone in einem realen Projekt kann man damit noch mehr Probleme aufdecken als nur kopierten Code. Sind Methoden inhaltlich identisch aber mit ganz anderen Namen versehen (wie beispielsweise GetOrder und GetPerson) gibt es wohl grössere Probleme beim Verstehen der Domäne.

Im besten Fall löst sich das Problem mit einer genaueren Erklärung der Domänenbegriffe. Es kann aber gerade so gut auch ein Warnzeichen für eine falsche Abstraktion oder gröbere Architekturfehler sein.

 

Einschränkungen

Code Clone hat 2 wichtige Einschränkungen:

  1. Diese Analyse benötigt die Premium und der Ultimate Version von Visual Studio 2012.
  2. Es werden nur Code-Teile berücksichtigt die aus 10 oder mehr Befehlen bestehen.

 

Fazit

Mit der Code Clone Analyse kann man ohne grossen Aufwand kopierte Codestücke auffinden. Dabei werden nicht nur 1:1 Kopien gefunden, sondern auch Teile die ähnlich sind. Die so gewonnenen Erkenntnisse sind eine gute Ausgangslage für ein Refactoring oder eine teamweite Code Review.

Schlagworte: ,
Folgen

Erhalte jeden neuen Beitrag in deinen Posteingang.

Schließe dich 296 Followern an