Software als Code-City

Kontinuierliche Architekturanalyse: Softwarevisualisierung mit SonarQube in 3-D

Stefan Rinderle

Mithilfe von Visualisierungen können große und komplexe Softwaresysteme einfach und übersichtlich erscheinen. Durch Technologien wie WebGL lassen sich komplexe 3-D-Visualisierungen erzeugen, die im Browser für alle Projektbeteiligten verfügbar sind. Das in diesem Artikel beschriebene SonarQube-Plug-in SoftVis3D bietet neben der Darstellung der Software als „Code-City“ ein neues Konzept, um die Abhängigkeiten zwischen den Klassen des Projekts zu visualisieren.

Jede Visualisierungsform bietet einen bestimmten Blick auf die dargestellte Softwarekomponente. Leider wird bei der Vorstellung von neuen Ansätzen immer wieder ein konkretes Problem deutlich: der Kontext. Was ist damit gemeint? Die Darstellung sollte einen direkten Bezug zu bereits existierendem Wissen herstellen. Ein Beispiel: Die Navigation innerhalb einer Stadt ist durch eine entsprechende Kartendarstellung deutlich vereinfacht. Straßen werden rot oder gelb dargestellt, Wald und Wiesenflächen in grün und Stadtteile und Gebäude in grau. Trotz dieser einheitlichen Darstellung wirken diese Karten aber je nach Kontext. Machen Sie einen Versuch: Als Erstes betrachten Sie eine Karte Ihrer Heimatstadt und versuchen diese zu interpretieren. Danach versuchen Sie die Interpretation mit einer Ihnen unbekannten Stadt. In der Heimatstadt lassen sich durch frühere Erfahrungen viel schneller Zusammenhänge erkennen. Die Interpretation ist dadurch vereinfacht und bringt effektiver Probleme oder Risiken zum Vorschein. Bei der unbekannten Stadt hingegen werden Sie einen groben Überblick bekommen, eine Interpretation wird Ihnen aber nur schwer möglich sein.

Die Herausforderung, einen geeigneten Kontext zu erzeugen, liegt bei der zugrunde liegenden Datenbasis. Die Visualisierung sollte die bisherigen Erfahrungen bzw. die zur Verfügung stehenden Metriken widerspiegeln. Die statische Codeanalyse ist hier ein gutes Beispiel. Es ist wichtig, dass erkannte Fehler in der Entwicklungsumgebung, dem Build-Server und natürlich auch in der Visualisierung gleichermaßen sichtbar sind. Besteht hier ein Bruch in der Datenbasis, ist eine Interpretation deutlich schwieriger.

Viele sehr gute Ansätze scheitern gerade an dieser Hürde. Beispiele erscheinen sinnvoll und erzeugen ein hohes Interesse des Publikums, lassen sich aber nur sehr schwer oder gar nicht auf das selbst zu entwickelnde Projekt abbilden oder umsetzen. Damit wird der Effekt der Visualisierungsform durch den fehlenden Kontext deutlich geschwächt und der Interpretationsspielraum verringert.

Continuous Inspection mit SonarQube

SonarQube schließt eine entscheidende Lücke im modernen Entwicklungszyklus und hat sich als Plattform für das Management von Codequalität etabliert. Durch die einfache Integration und die Vielzahl an unterstützten Sprachen und Analysen lassen sich schnell erste Ergebnisse generieren. Diese helfen allen Projektbeteiligten, die Qualität der gelieferten Software zu überwachen und zu steuern. Gerade im Java-Umfeld ist die Integration von SonarQube in den Entwicklungsprozess einfach und unkompliziert. Die Analyse des Projekts mit Maven wird über den Continuous-Integration-Server gesteuert und ist danach sofort verfügbar. Das Jenkins-Plug-in von SonarQube erleichtert die Konfiguration und stellt Links zu den Ergebnissen des jeweiligen Builds zur Verfügung.

Was wird analysiert? Einerseits werden bei der Analyse des Projekts Basismetriken wie die Anzahl an Codezeilen oder die Anzahl der Funktionen pro Klasse erstellt. Zusätzliche zur Verfügung stehenden Metriken, wie die Ergebnisse der Unit Tests und der Codeabdeckung, werden einfach über Plug-ins integriert. Bestehende Konfigurationen von statischen Codeanalysetools wie PMD, FindBugs oder Checkstyle können ebenfalls eingebunden werden. Es entsteht schnell ein über alle Ebenen einheitlicher Blick auf die Softwarequalität.

Einsatzbeispiel Quality Gates

SonarQube bietet nicht nur die Möglichkeit, die Ergebnisse der Analysen über die Zeit zu betrachten und zu analysieren. „Quality Gates“ ermöglichen es dem Entwicklungsteam, sich auf bestimmte Qualitätsmerkmale zu fokussieren und den eigenen Anspruch zu erfüllen. Beispielsweise einigt sich das Team darauf, dass die statische Codeanalyse keine Probleme mit der Stärke (Severity) Major oder höher aufweisen darf und alle Unit Tests erfolgreich sein müssen. Zudem ist ein zeitlicher Bezug möglich, was die Definition gerade für Wartungsprojekte oder Legacy-Software vereinfacht. Ein Beispiel hierfür wäre, dass neu geschriebener Code eine Testabdeckung von mindestens 80 Prozent aufweisen muss, oder die Testabdeckung seit der letzten Analyse nicht sinken darf.

Ob die Software der geforderten Qualität entspricht, wird bei jeder Analyse berechnet. Durch das Plug-in Build Breaker wird der aktuelle Build, wie der Name schon verrät, als instabil deklariert, wenn die Anforderungen des „Quality Gate“ nicht erfüllt werden. Diese Integration ermöglicht ein schnelles Feedback an den Entwickler und erhöht die Bedeutung von Softwarequalität innerhalb des Teams. Durch die Vielzahl an Möglichkeiten in der Konfiguration der Quality Gates können die Richtlinien Stück für Stück angepasst werden, um sukzessive die Qualität zu erhöhen.

Zurück zur Visualisierung

Was hat dies mit Softwarevisualisierung zu tun? Zum einen ist es entscheidend für den Projekterfolg, die Entwicklung der Softwarequalität im eigenen Produkt über einen längeren Zeitraum zu betrachten. Zum anderen spielt hier der Kontext wieder eine große Rolle. SonarQube vereinigt eine große Menge an Daten und Metriken als perfekte Ausgangsbasis für verschiedenste Visualisierungen. Tabellen, Grafiken, Treemaps und vieles mehr helfen bei der Interpretation der Ergebnisse auf allen Ebenen, vom Quellcode bis hin zur Aggregation auf Projektebene.

Ein aufgedeckter Fehler durch die statische Analyse sollte in der Entwicklungsumgebung und gleichermaßen in der Visualisierung erkennbar sein. Dieser Zusammenhang ist mit SonarQube gegeben. Das im Folgenden vorgestellte Plug-in SoftVis3D ist genau deshalb keine eigene Plattform, sondern lässt sich in den bestehenden Entwicklungsprozess integrieren. Dadurch können die Visualisierungen jederzeit von allen Projektbeteiligten analysiert und interpretiert werden. Damit wird vor allem die erste Hürde, um einen sinnvollen Kontext für die Visualisierung herzustellen, deutlich verkleinert.

Die Code-City

Bereits 1998 gab es die ersten Publikationen mit der Idee, Softwareprojekte mithilfe der „City-Metapher“ intuitiv und übersichtlich darzustellen. Klassen werden hierbei als Gebäude und Pakete als Stadtviertel visualisiert. Grundfläche, Höhe und Farbe der Gebäude können auf Basis von Metriken verändert werden. Vor allem die REVEAL-Forschungsgruppe, geleitet von M. Lanza in Lugano, beschäftigt sich seit Jahren mit diesem Thema. Eine ihrer empirischen Studien aus dem Jahr 2011 zeigt, dass die von ihnen gestellten analytischen Aufgaben mithilfe der Code-City-Visualisierung schneller bearbeitet wurden als mit aktuellen Explorationswerkzeugen. Auf Basis dieser Arbeit ist das Codecity-Plug-in für Eclipse entstanden.

Abb. 1: Code-City-Visualisierung der Eclipse Platform mit SoftVis3D

Abb. 1: Code-City-Visualisierung der Eclipse Platform mit SoftVis3D

Abbildung 1 zeigt die Code-City-Visualisierung des Eclipse-Plattform-Moduls org.eclipse.jdt.apt.core. Für die Gebäudegrundfläche wurde die Komplexität, für die Höhe die Anzahl der Codezeilen als Metrik verwendet. Diese Auswahl an Metriken ist wohl die natürlichste und gleichzeitig auch die am weitesten verbreitete. Bei der Interpretation der Visualisierung werden große, komplexe Klassen sofort als Wolkenkratzer sichtbar und können dann entsprechend genauer analysiert und gegebenenfalls bereinigt werden. Gerade bei größeren Projekten mit mehr als 200 000 Codezeilen bietet die Visualisierung einen schnellen Überblick.

Die Code-City-Visualisierung ist für alle Projektbeteiligten verständlich und bietet unter anderem eine gute Diskussionsgrundlage im Gespräch zwischen Projektleitung und Entwicklung. Die Größe und Komplexität des Softwaresystems wird deutlich, und technische Schulden werden sichtbar. Zudem kann die Darstellung das Entwicklungsteam dazu motivieren, technische Schulden kontinuierlich abzubauen, da dies auch in der Visualisierung zu sehen ist.

Erkunden Sie Ihre Stadt

Eine Stadt will erkundet werden, und das Plug-in SoftVis3D bietet dazu viele interaktive Möglichkeiten. An erster Stelle steht hier natürlich die Navigation durch die 3-D-Stadt. Sie erlaubt eine genauere Betrachtung einzelner Stadtteile und unterschiedliche Blickwinkel. Ohne zusätzliche Informationen oder Interaktionen entsteht aber die Gefahr der Fehlinterpretation. Um dieses Problem zu lösen, ist jedes Objekt innerhalb der Visualisierung auswählbar. Dies führt nicht nur zu einer entsprechenden Markierung des Gebäudes oder Stadtteils, sondern aktualisiert auch das Detailfenster auf der rechten Bildschirmseite. Hier werden alle relevanten Informationen des selektierten Objekts zusammengefasst. Neben dem Namen wird bei Stadtteilen die Struktur innerhalb des Pakets angezeigt. Ist ein Gebäude selektiert, werden unter anderem die konkreten Werte der zugrunde liegenden Metriken angezeigt. Auch hier sind alle Referenzen zu Klassen oder Paketen links, die zu einer Aktualisierung der Ansicht (markiertes Objekt) und des Detailfensters führen.

Auswahl von Metriken

Um den Benutzer zu Beginn nicht mit der Vielzahl an möglichen Kombinationen von Metriken zu erschlagen, bietet das Plug-in mehrere Standardvarianten an. Die geläufigste wurde schon in Abbildung 1 gezeigt (Komplexität, Anzahl Codezeilen und Änderungsrate). Hier steht ein guter Überblick über das Projekt und die Risikoanalyse im Vordergrund. Ein hoher und auch von der Grundfläche breiter Wolkenkratzer legt die Interpretation nahe, dass es sich hier um eine Gottklasse handelt. Aber wie viel Risiko steckt dahinter? Es kann entscheidend sein, wie vielen Änderungen diese Klasse unterliegt. Bei vielen Änderungen dieser Klasse können durch die hohe Komplexität natürlich leichter Fehler passieren. Zudem ist die Beobachtung des Umfelds der Klasse interessant. Ist es die einzige große, komplexe Klasse innerhalb des Projekts oder gibt es bestimmte Module, die durch die Häufigkeit solcher Klassen auffallen? Gibt es also ein kleines Manhattan innerhalb des Projekts? Aber auch hier ist der Kontext für die Interpretation entscheidend. Die Visualisierung sollte bei Projektbeteiligten aber auf jeden Fall zu einem „Aha“-Erlebnis führen.

Alle von Sonar erhobenen Metriken stehen für die Visualisierung zur Verfügung. Dies erlaubt eine Fokussierung auf bestimmte Problem- oder Risikofelder. Zu Beginn sollte nur die Metrik für die Gebäudegrundfläche verändert werden. Dadurch bleibt die Höhe der Gebäude bestehen, und der Benutzer findet sich schneller zurecht. Eine weitere Kombination ist aber gerade in Bezug auf die Softwarequalität sehr sinnvoll. Die Anzahl an Fehlern der statischen Codeanalyse bestimmt die Höhe des Gebäudes – die Anzahl an Codezeilen bestimmt die Grundfläche. Hier werden Risiken schnell sichtbar. Vor allem sind hohe, dünne Türme interessant. Kleine Klassen mit vielen Fehlern sind ein sehr guter Startpunkt bei der Behebung von Problemen.

Und wo bleibt die Architektur?

Die reine Paketstruktur bietet leider nur einen eingeschränkten Blick auf die Zusammenhänge zwischen den Klassen. Trotzdem impliziert die Anordnung der Dateien eine gewisse Gruppierung. Von Architektur kann deshalb aber nicht gesprochen werden. Um einen besseren Blick auf die Zusammenhänge der Klassen zu bekommen, werden deren Abhängigkeiten untereinander in die Visualisierung einbezogen. Über diese Verbindungen können spezifischere Rückschlüsse über die Kopplung von Klassen und deren Anordnung in der Struktur gezogen werden. Wird die Visualisierung aber ohne Anpassung mit dieser zusätzlichen Information angereichert, werden die folgenden Probleme sichtbar: Abhängigkeiten zwischen Klassen können in allen Ebenen der Struktur auftreten. Dies führt im ersten Schritt zu einem unübersichtlichen Netz, welches sich zwischen allen Gebäuden der Visualisierung aufspannt. Zudem werden viele Verbindungen von Gebäuden verdeckt und sind unsichtbar. Eine sinnvolle Analyse ist kaum noch möglich. Durch eine geeignete Zusammenfassung der Abhängigkeiten und einer Veränderung der Visualisierung kann jedoch ein übersichtlicheres Bild geschaffen werden.

Transformation und Aggregation von Abhängigkeiten

Wie bereits erwähnt, können Abhängigkeiten zwischen Klassen in allen Ebenen der Struktur auftreten. Die Visualisierung von Abhängigkeiten innerhalb eines Pakets oder Stadtteils ist relativ einfach und auch für den Betrachter übersichtlich. Die Verbindungen haben eine kurze Distanz und gehen nicht über die Stadtteilgrenze hinaus. Allerdings führen Abhängigkeiten über Paketgrenzen hinweg zu dem zuvor beschriebenen unübersichtlichen Netz. Um dieses Problem zu entschärfen, werden die Abhängigkeiten vor der Visualisierung transformiert und aggregiert (Abb. 2). Die Idee hinter der Transformation ist, die implizite Abhängigkeit zwischen Paket P2 und P3, die durch die Abhängigkeiten von Klassen C1 -> C3 und C2 -> C4 entsteht, sichtbar zu machen. Um dies zu erreichen, werden die Verbindungen über den kürzesten Pfad innerhalb der gegebenen Struktur geführt und dadurch aggregiert. Die Verbindung zwischen Paket P2 und P3 repräsentiert somit beide Abhängigkeiten.

Abb. 2: Transformation von Abhängigkeiten

Abb. 2: Transformation von Abhängigkeiten

Die Transformation löst Abhängigkeiten zwischen Klassen in unterschiedlichen Paketen und somit auch das unübersichtliche Netz zwischen den Gebäuden auf. Eine bessere Sicht auf die Verbindungen entsteht aber leider noch nicht, da diese immer noch hinter den Gebäuden verschwinden.

Visualisierung von Abhängigkeiten

In Abbildung 2 wurden die Abhängigkeiten inklusive der Struktur der Klassen und Pakete mithilfe eines klassischen Baumdiagramms gezeigt. Durch die hierarchische Darstellung von oben nach unten wird die Struktur sehr gut sichtbar. Was passiert nun, wenn diese Visualisierungsform mit der Codestadt verbunden wird? Es bleibt dabei, dass sich die Gebäude in Stadtteilen befinden. Die Stadt wird aber nicht mehr von unten nach oben, sondern aggregiert von oben nach unten gebaut. Abbildung 3 zeigt die Visualisierung der Abhängigkeiten von Abbildung 2. Hier hat jeder Stadtteil eine Repräsentation als Plattform auf der oberen Ebene, entsprechend den Paketknoten aus Abbildung 2, und zeigt die aggregierten Abhängigkeiten. Die Abhängigkeiten über mehrere Ebenen werden über zusätzlich eingeführte Verbindungsgebäude geleitet. Jede Verbindung aus dem jeweiligen Paket nach innen oder außen wird durch dieses Gebäude gelenkt, um die Übersichtlichkeit zu verbessern.

Abb. 3: Transformation von Abhängigkeiten

Abb. 3: Transformation von Abhängigkeiten

Im Folgenden eine Zusammenfassung der Visualisierung von Abhängigkeiten:

  • Abhängigkeiten innerhalb eines Pakets werden über einen direkten Pfeil dargestellt.
  • Abhängigkeiten nach außen werden mittels kürzestem Pfad transformiert und aggregiert.
  • Stadtteile wachsen nach unten und werden auf der oberen Ebene als Plattform repräsentiert.
  • Verbindungsgebäude vereinen alle ein- und ausgehenden Verbindungen des Pakets.
  • Das Plug-in bietet eine aggregierte Sicht der Abhängigkeiten von Klassen und Paketen.

SoftVis3D Dependency View

Bei der Dependency View ist die Auswahl der Metriken nicht so entscheidend wie in der Code-City-Ansicht. Um einen entsprechenden Kontext herzustellen, ist es wichtig, die Gebäude in der Ansicht der Abhängigkeiten zu unterscheiden und wiedererkennen zu können. Die Interaktion mit der Visualisierung bleibt bestehen. Jedes Objekt kann ausgewählt werden, und das Detailfenster wird entsprechend aktualisiert. Hinzu kommen natürlich die Informationen über die Abhängigkeiten des ausgewählten Gebäuds bzw. der Plattform. Diese sind nach ein- und ausgehenden Verbindungen gruppiert und geben zusätzlich einen Einblick in die konkreten Abhängigkeiten zwischen den Klassen. Ein Klick auf diese markiert die Pfeile über den transformierten Weg der Abhängigkeit über die Struktur in rot.

Abb. 4: Ausschnitt aus dem Projekt Groovy (Core)

Abb. 4: Ausschnitt aus dem Projekt Groovy (Core)

Abbildung 4 zeigt einen Ausschnitt der Visualisierung von Abhängigkeiten des Projekts Groovy (Core). Im Gegensatz zur sehr intuitiven und schnell zu analysierenden Darstellung als Code-City ist hier mehr Detailarbeit und exploratives Vorgehen nötig. Zudem benötigt man deutlich mehr Systemwissen, um die angezeigten Abhängigkeiten auf Risiken oder Probleme zu analysieren.

Entsprechen Ihre Architekturbilder der Wahrheit?

Jedes Softwareprojekt hat eine Architektur auf dem Papier und eine Architektur im Code. Die entscheidende Frage ist, in wie weit sich diese unterscheiden oder an welchen Stellen es Verstöße gegen die Zielarchitektur gibt. Eine Analyse der Unterschiede ist auf Basis des reinen Quellcodes sehr schwierig und mühsam. Deshalb existieren mehrere Ansätze, um z. B. über Annotationen Architekturinformationen im Quellcode zu verankern und möglichst früh Probleme zu erkennen. Die hier vorgestellte Visualisierung kann dabei helfen, die Unterschiede sichtbar zu machen.

Ein sehr guter Startpunkt für die Analyse des eigenen Projekts sind zyklische Abhängigkeiten. Diese lassen sich dadurch erkennen, dass zwei Pfeile zwischen zwei Plattformen quasi parallel verlaufen. Hierbei werden vor allem auch kleinere Verstöße gegen die Architektur schnell sichtbar, wenn beispielsweise von Paket A hundert Abhängigkeiten nach Paket B, aber nur drei Abhängigkeiten von Paket B nach Paket A existieren. In der Visualisierung wird dies über einen sehr dicken Pfeil in die eine und einen sehr dünnen Pfeil in die entgegengesetzte Richtung sichtbar. Ein gutes Beispiel hierfür ist ein klassisches UTIL-Paket, welches in mehreren Projekten verwendet werden soll, aber Abhängigkeiten zu dem eingesetzten Projekt aufweist. Bei der Wiederverwendung wird dies zu Problemen führen, die sich durch die Visualisierung bereits vorher erkennen und auflösen lassen – ohne Detailanalyse im Code und verständlich für alle.

Fazit

Softwarevisualisierung macht Spaß und ist für alle im Projekt interessant, vom Entwickler bis zum Projektleiter. Durch eine kontinuierliche Analyse des Quellcodes kann von der Entwicklungsumgebung über die Auswertungen in SonarQube bis hin zur Visualisierung ein geeigneter Kontext hergestellt werden. Die intuitive Code-City-Ansicht zeigt die Struktur des Projekts und erlaubt eine schnelle Risikoanalyse. Die Ansicht der Abhängigkeiten ist komplexer zu verstehen und zu analysieren, zeigt dafür aber die wahren Zusammenhänge zwischen den Klassen und Paketen des Projekts. Das Plug-in zum Download und Demos finden Sie hier. Ich freue mich schon auf Ihr Feedback.

Verwandte Themen:

Geschrieben von
Stefan Rinderle
Stefan Rinderle
Stefan Rinderle arbeitet seit 2013 als Software-Engineer bei der Payback GmbH in München und ist für die Konzeption und Realisierung von Informationssystemen auf Basis von Java EE verantwortlich.
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu: