Blog

Zirkuläre Abhängigkeiten mit Sonar orten

Komplexe Java-Anwendungen bestehen normalerweise aus einzelnen Komponenten. In diesen sind fachliche Logik, Benutzeroberfläche, die Datenhaltungsschicht oder auch Schnittstellen zu externen Systemen gekapselt.

Den einzelnen Komponenten können dann klar umrissene Verantwortlichkeiten zugeteilt werden. Dies verhindert Redundanzen, da Code für ein und dieselbe Aufgabe nur in genau einer Komponente implementiert werden muss. Diese stellt ihre Funktionalität dann über eine klar definierte Schnittstelle nach außen zur Verfügung. Andere Komponenten nutzen diese Schnittstelle, ohne diese Funktionalität noch einmal selbst implementieren zu müssen.

Somit ergeben sich Abhängigkeiten zwischen Komponenten in einer Anwendung, die beispielsweise in UML durch die uses-Relation dargestellt werden.

Abhängigkeit zwischen Klassen: Class1 uses Class2

Abbildung 1: Abhängigkeit zwischen Klassen: Class1 uses Class2

Dabei muss darauf geachtet werden, dass zwischen den Komponenten keine zirkulären Abhängigkeiten entstehen, d.h., zwei Komponenten dürfen keine gegenseitigen Abhängigkeiten haben.

Zirkuläre Abhängigkeit zwischen Klassen Class1 und Class2

Abbildung 2: Zirkuläre Abhängigkeit zwischen Klassen Class1 und Class2

Zirkuläre Abhängigkeiten können, wie in Abbildung 2, direkt vorkommen oder auch indirekt, wie in Abbildung 3.

Zirkuläre Abhängigkeit zwischen Klassen Class1, Class2 und Class3

Abbildung 3: Zirkuläre Abhängigkeit zwischen Klassen Class1, Class2 und Class3

Zirkuläre Abhängigkeiten auf Klassenebene führen im schlimmsten Fall zu Totschleifen oder Memory-Leaks. Auf Komponentenebene sind sie meist ein Indiz für schlechtes Design, wie etwa ungünstig verteilte Zuständigkeiten. Meist sind es Implementierungsfehler der Art, dass Anwendungslogik am falschen Ort, also nicht in der dafür vorgesehenen Komponente liegt.

In jedem Fall sollten zirkuläre Abhängigkeiten jedoch, sofern sie bekannt sind, Anlass für ein Code-Refactoring sein.

Das Sonar suchen lassen

Ein ideales Werkzeug zum Aufdecken dieser Abhängigkeiten ist Sonar und dort speziell der Bereich Design.

Design-Bereich in Sonar

Abbildung 4: Abschnitt Design in der Sonar-Navigation (anklicken, um zu vergrößern)

Im Design-Bereich sehen wir eine Matrix, in der die X- und die Y-Achse jeweils die einzelnen Komponenten des aktuellen Projektes darstellen. Aus Platzgründen ist nur die Y-Achse beschriftet. Auf der X-Achse sind jedoch dieselben Komponenten aufgelistet. Zeile 1 und Spalte 1 sind im hier gezeigten Beispiel jeweils die Komponente de.ejb3buch.ticket2rock. Am Schnittpunkt von Zeile 1 und Spalte 1 wird deswegen ein Bindestrich angezeigt.

Design-Matrix in Sonar

Abbildung 5: Volle Ansicht des Design-Bereichs in Sonar (anklicken, um zu vergrößern)

An anderen Schnittpunkten zwischen unterschiedlichen Komponenten sehen wir ein leeres Kästchen, wenn keinerlei Abhängigkeiten zwischen Komponenten bestehen. Bestehen Abhängigkeiten, so wird im Schnittpunkt die Anzahl der Zugriffe der Kompontente aus der X-Achse auf die Komponente aus der Y-Achse angezeigt.

In Abbildung 5 sehen wir zum Beispiel relativ weit oben links, dass de.ejb3buch.ticket2rock.applikation.controller viermal auf de.ejb3buch.ticket2rock.applikation.helper zugreift.

Interessant sind in dieser Übersicht die rot markierten Felder. Diese zeigen zirkuläre Abhängigkeiten.

Anzeige einer zirkulären Abhängigkeit in Sonar

Abbildung 6: Anzeige einer zirkulären Abhängigkeit in Sonar

Ein Klick auf das rot markierte Feld zeigt anschließend durch weitere farbliche Markierungen an, zwischen welchen Komponenten genau die zirkuläre Abhängigkeit besteht. Dies ist in Abbildung 6 dargestellt.

In unserem Beispiel sind dies:

  • de.ejb3buch.ticket2rock.exception
  • de.ejb3buch.ticket2rock.entity

Durch ein Code-Refactoring sollte diese Abhängigkeit aufgelöst werden. Mit wenigen weiteren Mausklicks führt Sonar direkt zu den Zeilen im Quellcode, die die Abhängigkeiten verursachen.

Fazit

In komplexen Anwendungen ist es ohne technische Hilfe kaum möglich, zirkuläre Abhängigkeiten ausfindig zu machen. Sie kommen erfahrungsgemäß nicht selten vor und das Ziel sollte sein, sie zu finden und zu beseitigen. Sonar ist für diese Aufgabe ein ideales Werkzeug.

Der Installationsaufwand dafür wird sich schnell wieder durch bessere Code-Qualität amortisieren. Siehe dazu auch unseren Artikel Was kostet Software Lifecycle Management – wenn man darauf verzichtet?

Holisticon AG — Teile diesen Artikel

Über den Autor

Jan beschäftigt sich sich seit knapp sieben Jahren mit dem Design, der Entwicklung und der Verbesserung von verteilten Web- und Unternehmensanwendungen. Die Erstellung solider, qualitativ hochwertiger Software, sowie deren Wartbarkeit liegen ihm dabei besonders am Herzen. Jan Weinschenker ist Organisator des Web-Performance-Meetups Hamburg.

Antwort hinterlassen