Freitag, 9. April 2010

NDepend einmal angewendet

In meinem kleinen Bericht zu NDepend hatte ich einen Screenshot eines Abhängigkeitsgraphen von einem Aktuellen Projekt. Auf diesem sieht man zyklische Abhängigkeiten zwischen Namespaces.

Diese erkennt man daran, dass die Pfeile in beide Richtungen Zeigen. Nehmen wir als Beispiel die Verbindung zwischen Scrum.Org.ApplicationLayer und Scrum.Org.TeamConfiguration. Diese Abhängigkeit entsteht dadurch, dass in ApplicationLayer eine Factory ist, die mir bestimmte Klassen der TeamConfiguration erzeugt. Die Klassen der TeamConfiguration wiederum verwenden die Factory um selbst neue Klassen zu instanziieren.

Um diesen Kreis aufzulösen habe ich die einzelnen Factory-Methoden, die nur die Teamconfiguration verwendet, in ein eigenes Interface ITeamApplicationFactory gesteckt und das Interface in den entsprechenden Namespace verschoben. Der daraus resultierende Graph sieht nun so aus.


Hier sieht man nun keine zirkularen Abhängikeiten mehr und die Klassenhirachie gefällt mir auch besser.

Dienstag, 6. April 2010

NDepend

Wie im letzten Post angekündigt wollte ich mich mit NDepend auseinandersetzen. Leider ist der Zeitabstand zwischen den Posts etwas größer geworden, da ich kaum Zeit finde mich zum Einen mit NDepend zu befassen und zum Anderen einen Artikel darüber zu schreiben

Interessant ist dieses Tool allemal. Mit NDepend kann man seine .NET Assemblies analysieren und sich diverse Infos zum Aufbau des Codes ausgeben lassen. Dabei wird man zu Beginn mit einer Reihe von Informationen überflutet die es auszuwerten gilt.

Für die Analyse muss man die Assemblies auswählen, die man betrachten will. Nach ein paar Sekunden bekommt man einen Bericht im Web-Browser angezeigt und die detaillierten Auswertungen in NDepend selbst.

Der Bericht im Browser zeigt im Prinzip alle Ergebnisse der Analyse an die man auch in NDepend selbst nachschauen kann. Man hat dadurch einen direkten Überblick über Lines of Code, Abhängigkeiten, verletzte Vorgaben wie z.B. überschreiten einer maximalen Methodenlänge. Was im Bericht angezeigt werden soll kann man in NDepend inklusive eigener Analyse-Abfragen konfigurieren.

An dieser Stelle kann man nun mit NDepend selbst arbeiten. Durch ein paar vorgegebene Constraints werden einem direkt Stellen im Programm angezeigt, die allem Anschein nach nicht gut designed sind oder irgend welche Vorgaben verletzen. Wenn das Projekt zu groß ist kann man sich langsam durch abgegrenzte Code-Bereiche hangeln bis dieser entsprechend überschaubar ist. Zu jedem Namespace, Typen und Methode kann man sich die direkten Abhängigkeiten anzeigen lassen.

Im Graphen sieht man welcher Typ genau von welchem anderen Typen abhängt. Will man den weiteren Aufbau sehen so kann man in eine Klasse "hinein Zoomen" um die inneren Abhängigkeiten zu betrachten.
Hier z.B. lasse ich mir den inneren Graphen von "Scrum.Org" anzeigen.
In der Matrix kann man noch genauer sehen, was von wem wie oft verwendet wird. Vom Namespace aus kann man immer weiter runter bis in die jeweilige Klasse navigieren analog zu der Graphenansicht.
Beide Ansichten zeigen zirkulare Abhängigkeiten an, markiert durch die dickeren Pfeile die im Graphen in beide Richtungen zeigen. In der Matrix werden diese mit einem roten Rahmen versehen. Um dies verwenden zu können setzt es voraus, dass man seine Applikation entsprechend nach Namespaces strukturiert hat. Ansonsten sind die Ergebnisse nicht wirklich aussagekräftig, siehe diskussion um NHibernate Codebasis

NDepend  bringt von Haus aus schon eine Menge vordefinierte Abfragen zur Codanalyse mit, die einem Assemblies, Namespaces, Typen, Methoden und Fields anzeigen, wenn der Code bestimmten Konditionen entspricht. Zum Beispiel wird angezeigt, wenn eine Methode zu lang ist. Dies kann mit der Hilfe von CQL (Code Query Language) auch selbst definiert werden.

Als Beispiel kann man mit:
SELECT TYPES WHERE NbFields > 20
alle Klassen anzeigen die mehr als 20 Fields beinhalten. So hat man jede Menge Möglichkeiten den Code nach unerwünschten Fragmenten zu durchsuchen. Man kann sogar die Testabdeckung ermitteln wenn man die Analysen von NCover oder MS VS Team System verwendet. Leider konnte ich diese Funktionialität noch nicht testen, da irgend wie der Import der NCover-Datei nicht den gewünschten Erfolg mit sich brachte.Vom gefundenen Ergebnis aus kann man direkt an die entsprechende Stelle im Quellcode "springen".

Wirklich toll fand ich die Abfrage nach der Komplexität einer Methode. Diese zählt Bedingungsoperatoren wie z.B. "if", "foreach" oder "&&". Daraus kann man formal ermitteln, wie komplex eine Methode ist. Zu jeder dieser Abfragemöglichkeiten gibt es auf der NDepend-Seite eine genaue Beschreibung und auch Ratschläge wie damit umzugehen ist.

Was mir jedoch bei der Ermittelung der Komplexität fehlte war die Einbeziehung der Schachtelungstiefe innerhalb einer Methode. Aber wenn ich das richtig sehe, kann man IlNestingDepth dafür verwenden.

Bei den ganzen Analysemöglichkeiten stellt sich mir nun die Frage, wann sollte ich jedesmal meinen Code analysieren? Vorallem wann sollte ich den Code entsprechend refaktorisieren? Denn Code der schon lange läuft, funktioniert und bei dem es keine Erweiterung gibt sollte meines Erachtens nicht refaktorisiert werden. Erst wenn ich an dieser Stelle etwas ändern will und ich einen Nutzen von den Refaktorisierungsmaßnamen habe macht dies auch Sinn, damit ich eine verbesserte Erweiterbarkeit habe. Alles andere wäre Refaktorisierung zum Selbstzweck und unter Umständen unnötig gefährlich.

Ich denke sinnvoll ist es die Analyse jedesmal durchzuführen, wenn man in einem Bereich mit einer Erweiterung beginnt und nachdem man fertig ist. Bei Beginn kann man direkt sehen, wo eine Refaktorisierung wichtig wäre. Wenn man seine Arbeiten abgeschlossen hat kann man formal kontrollieren, ob der Code den eigenen Ansprüchen genügt und eventuell direkt auf Schwachstellen reagieren.

Zum Abschluss will ich noch sagen, dass NDepend für mich lediglich einen sehr guten Anhaltspunkt bietet, wo man aufräumen sollte. Es werden stellenweise Sachen im Code bemängelt die bewußt so gestaltet wurden und troz der Warnung von NDepend gut organisiert sind. Ich werde mich in Zukunft noch weiter mit Code-Metriken beschäftigen und schauen, in wie weit man diese für eine bessere Codebasis verwenden kann.

Kurz bevor ich mit dem Artikel fertig wurde erhielt ich noch ein Liezenzupgrade für die neue 3er Version. Ich werde warscheinlich noch einemal in ein paar Wochen über die Neuerungen berichten.

Ihr könnt es ja einfach einmal selbst ausprobieren. Eine freie Version kann hier heruntergeladen werden.

Samstag, 7. November 2009

Wie komme ich zu der Ehre?

Gerade vom .Net Open Space zurück starte ich meinen E-Mail Client und sehe eine Mail von einem Patrick Smacchia. Ich hatte bis jetzt noch nie von ihm gehört. In der E-Mail fragt er mich ob ich mir NDependend anschauen kann und eventuell mal hier darüber berichten könnte. Ich war erstmal etwas skeptisch und verunsichert. Warum werde gerade ich gefragt? Naja nun habe ich hier NDependend zum ausgiebigen Testen liegen. Es scheint ein sehr interessantes Tool zu sein, leider hatte ich bisher noch nicht die Zeit mir sämtliche Features anzuschauen. Ich werde mich aber in Kürze weiter damit beschäftigen und ausgibig berichten, was das Tool genau kann und in wie fern es brauchbar ist.

Sonntag, 18. Oktober 2009

.Net Open Space 2009

Puh. Ich bin gerade erst von der .Net Open Space zurück. Es gab wieder viel zu lernen. Für mich selbst waren die interessanten Themen Clean Code, Teambildung, Entwicklungsprozesse und Architektur. Im letzten Jahr ging es mehr um TDD und BDD.

Zu Beginn gab es von Stefan Lieser eine kleine Einführung in die Open Space Philosophie. Danach ging es direkt in die Themenfindung für die einzelnen Sessions. Nach Wahl der Sessions besuchte man den entsprechenden Raum.



Dies war die Session "Architektur technologieunabhängig?" in der meine persönliche Erkenntnis war, dass ich mich kontinuierlich weiterbilden muss. Vor allem auch zielungerichtet um mal einen Blick über den Tellerrand zu bekommen.


Zwischen den Sessions gab es immer genügend Zeit sich mit den anderen Teilnehmern auszutauschen. Hier gab es Gespräche über konkrete Applikationen, Tools, Entwicklungsmethodiken und Entwicklungsprozesse. Eigentlich alles, was irgend wie mit der Sofwareentwicklung zu tun hat.


Eine der für mich interessantesten Sessions war die KattaPotter Dojo Session. Hier sollte von sechs Teilnehmern eine Übungsaufgabe gemeinschaftlich gelöst werden.


Es war schon interessant zu sehen, wie kompliziert manche im ersten Ansatz versuchen an eine Aufgabe heranzugehen. Dabei wurde die eigentlich Problematik völlig ausser acht gelassen. Warscheinlich werde ich die Katta in Kürze selbst machen und von meinen Erfahrungen berichten. Denn ich befürchte, ich hätte es an einigen Stellen genau so gemacht.

Alles in allem war die diesjährige .NET Open Space super. Ich habe viel gelernt und werde auch nächstes Jahr wieder in Leipzig sein. Jetzt muss ich erst mal ein wenig Schlaf nachholen ;-)

Freitag, 2. Oktober 2009

Update zu "Bug in NHibernate 2.1 die Dritte"

Mein Patch zu dem Bug über den ich in diesem Post berichtete wurde mittlerweile doch aktzeptiert.

Update zu "Bug in NHibernate 2.1 die Zweite"

Wie in einem meiner vorherigen Posts zu lesen war, gab es Probleme mit One-To-Many und access="none"

Richard Brown hat mich darauf hingewiesen, dass das Setzen des Bags im Parent auf inverse="true" das Problem behebt.

Aber seltsam ist das Verhalten doch trozdem. Ich frage mich, ob das so gedacht war.

Samstag, 5. September 2009

NHibernate 2.1 short codereview

Um erst einmal eins vorweg zu sagen, ich mag NHibernate wirklich sehr. Ich will dieses Tool nicht schlecht machen oder so, auch wenn ich in letzter Zeit viel über Bugs oder komische Codestellen berichte. Es ist ein sehr gutes Tool und wenn mir die Qualität nicht passt habe ich selbst die Möglichkeit etwas dran zu ändern.

Da ich in letzter Zeit vermehrt in den Sourcecode von NHibernate reingeschaut habe, sind doch ein paar Stellen aufgefallen die ich einfach grottig fand. Eine von diesen werde ich kurz erläutern.

In der Klasse Configuration gibt es die Methode BuildSessionFactory(). Diese sieht momentan so aus:

public ISessionFactory BuildSessionFactory()
{

    ConfigureProxyFactoryFactory();
    SecondPassCompile();
    Validate();
    Environment.VerifyProperties(properties);
    Settings settings = BuildSettings();

    // Ok, don't need schemas anymore, so free them
    Schemas = null;

    return new SessionFactoryImpl(this, mapping, settings, GetInitializedEventListeners());
}

 Die rot markierte Zeile ist das Interessante an der Sache. Wenn ich so in den Qullcode schaue, würde ich ja denken hier werden Properties überprüft. Wenn wir uns nun mal die Methode anschauen stellen wir fest ...

/// <summary>
/// Issue warnings to user when any obsolete property names are used.
/// </summary>
/// <param name="props"></param>
/// <returns></returns>
public static void VerifyProperties(IDictionary<string, string> props) {}

sie macht garnichts!
Sehr cool finde ich den Kommentar.