Mittwoch, 9. Juli 2014

Zyklische Abhängigkeiten - die Praxis

Dieser Artikel ist Teil der folgenden Serie über zyklische Abhängigkeiten. Zahlreiche Grundbegriffe, Konzepte und empirische Befunde wurden im Rahmen dieser Serie detailliert dargestellt. Im vorliegenden Artikel stelle ich einige wissenschaftliche Studien vor, welche das Auftreten zyklischer Abhängigkeiten in der Praxis untersucht haben.

Die Serie

Einführung
Terminologie
Werkzeugunterstützung für Java
Wo liegt eigentlich das Problem?
Einfluss auf Qualitätsmerkmale
Die Praxis (dieser Artikel)
Verschiedene Erscheinungsformen
Zusammenhang mit der Pakethierarchie
Zusammenhang mit der Domäne
Einige Metriken
Durchbrechung von Zyklen
Das Prinzip

Die Brandmarkung zyklischer Abhängigkeiten begann mit Nachdruck in der Mitte der 1990er Jahre. Insbesondere Robert C. Martin und John Lakos vertraten ab dieser Zeit sehr eindeutige Positionen und forderten zumindest auf Package-Ebene absolute Freiheit von Zyklen ein. Erst zu Beginn der 2000er Jahre begannen sich erste Forscher dem Thema zyklischer Abhängigkeiten zu widmen. Der vorliegende Artikel stellt einige Studien vor, die sich insbesondere der Frage zuwenden, in welchem Ausmaß Zyklen in realen Software-Systemen auftreten.

Erste empirische Studie (2002)

Eine der ersten Studien, die Analysen zum Auftreten von Zyklen in der Praxis präsentierte, wurde von Edwin Hautus 2002 unter dem Titel "Improving Java Software Through Package Structure Analysis" [Hautus2002] veröffentlicht. Die Studie fokussiert auf Abhängigkeiten zwischen Packages in Java-Software. Sie war in mehrfacher Hinsicht neuartig:
  • Sie stellte eine Metrik vor, welche das Ausmaß unerwünschter Paket-Abhängigkeiten unter Berücksichtigung zyklischer Abhängigkeiten ermöglichte.
  • Mittels dieser Metrik wurden die Packages einiger frei verfügbarer Java-Werkzeuge untersucht. In einer Fallstudie wurden dabei insbesondere einige unerwünschte Zyklen im Java JDK 1.4 offengelegt.
  • Auf der Basis der Metrik konnten Vorschläge generiert werden, an welchen Stellen sich die Zyklen am ehesten durchbrechen lassen.
Diese als PASTA (für Package Structure Analysis) bezeichnete Metrik ließ zwar einige Fragen offen, und auch die empirischen Ergebnisse sind in der genannten Studie eher oberflächlich dargestellt. Doch diente sie späteren Autoren als Einstieg in die empirische Untersuchung von Zyklen.

Zyklen in Klassen (2006)

Die bis heute umfangreichste empirische Studie zur Verbreitung von Zyklen in Java-basierten Software-Systemen stammt von Hayden Melton und Ewan Tempero [Melton2006]. Dort wurden insgesamt 78 Software-Systeme hinsichtlich enthaltener Zyklen untersucht. Einige wesentliche Eigenschaften dieser Studie waren:
  • Im Gegensatz zur Hautus-Studie wurde auf Zyklen der Klassen-Ebene fokussiert.
  • Es wurde je System die Anzahl und die Größe der Zyklen (als Anzahl der beteiligten Klassen) ermittelt.
  • Es wurde eine Metrik eingeführt, welche die Stärke der Verbundenheit (engl. strength of connection) von Zyklen messen kann, um erste Hinweise auf die potentiellen Aufwände der Beseitigung eines Zyklus' zu erhalten.
Die Studie ergab, dass ca. 85% aller untersuchten Systeme Klassenzyklen mit mehr als 10 Klassen enthalten. 40% aller Systeme enthalten Klassenzyklen mit mehr als 100 Klassen. Und immerhin 10% aller Systeme, die mehr als 1000 Klassen enthalten, enthalten auch Zyklen mit mehr als 1000 Klassen. Der größte gefundene Zyklus enthielt 2145 Klassen.

Die Studie zeigte somit erstmalig die globale Verbreitung von Klassenzyklen in modernen Software-Systemen.

Zyklen in Paketen und physischen Einheiten (2010)

In der Studie "Barriers to Modularity - An empirical study to assess the potential for modularistation of Java programs" [Dietrich2010] untersuchten die Autoren die Eignung von insgesamt 87 Software-Systemen zur Verwendung fortgeschrittener Modulsysteme wie beispielsweise OSGi. Um diese Eignung zu untersuchen, wurden einige Antipatterns vorgeschlagen, welche eine Modularisierung in diesem Sinne erschweren können. Zwei dieser Antipatterns sind Cycles between Name Spaces (CDNS) und Cycles between Containers (CDC). Diese beiden Muster entsprechen zyklischen Abhängigkeiten auf der Ebene von Paketen (hier Name Spaces genannt) und physischen Einheiten (hier Container genannt). Wesentliche Ergebnisse der Studie mit Blick auf Zyklen sind:
  • Lediglich vier der 87 untersuchten Systeme weisen keine Zyklen auf Paket-Ebene auf.
  • Immerhin 17 der untersuchten Systeme weisen auch Zyklen auf der Ebene physischer Einheiten auf.

Vom Bestreben, Zyklen zu beseitigen (2014)

In der Studie "Transition and Defect Patterns of Components in Dependency Cycles during Software Evolution" [Oyetoyan2014], die insbesondere den Einfluss von Zyklen auf die Fehleranfälligkeit der Software untersuchte, wurde u. a. auch erhoben, wie häufig sich in der Versionshistorie dieser Software eine Durchbrechung von Zyklen nachweisen lässt. Zu diesem Zweck wurden die historischen Versionen von vier Software-Systemen jeweils auf Zyklen hin untersucht. Für jede Klasse wurde in jeder Version untersucht, ob sie an einem Zyklus beteiligt ist oder nicht. Auf diese Weise konnten Zustandsübergänge für Klassen zwischen einzelnen Releases ermittelt werden:
Von besonderem Interesse war dabei, wie häufig es vorkommt, dass eine Klasse, die "In-Cycle" ist, in den Zustand "Out-Of-Cycle" übergeht. Dies könnte als ein Zeichen gewertet werden, dass die Entwickler eine Restrukturierung mit dem Ziel der Beseitigung oder Verkleinerung von Zyklen vorgenommen haben. Obwohl einige andere Eigenschaften die Vermutung nahegelegt haben, dass es durchaus Restrukturierungen in den betroffenen Systemen gab, konnten dennoch fast keine "In-Cycle" -> "Out-Of-Cycle"-Übergänge gefunden werden. Die Studie konnte demgemäß keinerlei Bestreben der Entwickler nachweisen, Zyklen aktiv zu beseitigen.

Zusammenfassung

Betrachtet man die Studien [Melton2006] und [Dietrich2010] zusammen, so ergibt sich auf der Grundlage einer vergleichsweise großen und repräsentativen Datenbasis, dass Zyklen auf allen Ebenen (Typen, Pakete und physische Einheiten) in Software-Systemen unterschiedlichster Größen und in den verschiedensten Domänen auftreten. Die geringste Anzahl von Zyklen ergibt sich erwartungsgemäß für physische Einheiten. Da hier aber ein Zyklus den Existenzgrund der jeweiligen physischen Einheit insgesamt in Frage stellt, erscheinen der Anteil von 20% betroffener Systeme immnoch als ein sehr hoher Wert.

Die Studie [Oyetoyan2014] zeigt zudem, wenn auch auf Grundlage einer weniger breiten Datenbasis, dass seitens der Entwickler praktisch keine nennenswerten Aufwände betrieben werden, um Zyklen durch Refactorings zu durchbrechen.

Quellen

[Dietrich2010] - Barriers to Modularity - An Empirical Study to Assess the Potential for Modularisation of Java Programs, Jens Dietrich, Catherine McCartin, Ewan Tempero, Syed M. Ali Shah (2010)
 

[Hautus2002] - Improving Java Software Through Package Structure Analysis, E. Hautus (2002)

[Melton2006] - An Empirical Study of Cycles among Classes in Java,  H. Melton, E. Tempero (2006)

[Oyetoyan2014] - Transition and Defect Patterns of Components in Dependency Cycles during Software Evolution, Oyetoyan, T.D., Cruzes, D.S., Conradi, R. (2014), siehe Preprint unter https://www.idi.ntnu.no/~tosindo/publications/CSMR-WCRE14_pre_print.pdf