Donnerstag, 10. Juli 2014

Zyklische Abhängigkeiten und die Pakethierarchie

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 behandle ich einige Zusammenhänge zwischen zyklischen Abhängigkeiten und ihre Einbettung in die Pakethiearchie eines Software-Systems.

Die Serie

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

Software-Systeme tendieren dazu, mit der Zeit zu wachsen, und dieses Wachstum erfolgt auch auf der Paketebene. Pakete, die mehr als eine gewisse Anzahl von Klassen enthalten, werden oftmals als unhandlich empfunden. Wo genau diese Grenze liegt, kann von Entwickler zu Entwickler, von Organisation zu Organisation stark schwanken. In manchen Fällen wird dies von Richtlinien entschieden, in anderen Fällen entscheiden die Entwickler individuell.

Restrukturierung zu großer Pakete

Nehmen wir an, ein Paket überschreitet das als akzeptabel angesehene Größenmaß. Dann besteht die naheliegende Maßnahme darin, das Paket in mehrere Pakete aufzuteilen. Eine Möglichkeit ist es, ein zweites Paket auf derselben Ebene zu erstellen und einen Teil der Klassen dorthin zu verschieben. Da aber die Klassen meist in einem engen Zusammenhang stehen, kann es auch sinnvoll sein, das vorhandene Paket bestehen zu lassen und ihm zwei Unterpakete hinzuzufügen. Der enge Zusammenhang wird dann weiterhin durch das gemeinsame Elternpaket angezeigt, das entweder leer sein kann oder Klassen enthält, die für beide Unterpakete relevant sind. Eine solche Umstrukturierung könnte wie folgt aussehen:
Die zyklenfreie Klassenstruktur des ursprünglichen Pakets bleibt nach der Umstrukturierung unverändert. Diejenige Klasse, die gewissermaßen als Knotenpunkt zwischen zwei eng zusammenhängenden Gruppen fungiert, ist als einzige im ursprünglichen Paket geblieben, während die Klassen der beiden Gruppen in neue Unterpakete verlagert wurden. Auf Paketebene ist nun aber bedauerlicherweise ein Zyklus aus drei Paketen entstanden, obwohl es zuvor noch nicht einmal einen Klassenzyklus gab.

Zyklen in Zweigen der Pakethierarchie

In der Studie "Efficient Retrieval and Ranking of Undesired Package Cycles in Large Software Systems" [Laval2011] wurde erstmalig argumentiert, dass Paket-Zyklen dieser Art vermutlich weniger problematisch einzustufen sind als Zyklen, die sich weniger regulär auf die Pakethierarchie verteilen. 

Zyklen innerhalb eines Zweiges der Pakethierarchie könnten durch gewollte Umstrukturierungen wie die obige entstanden sein. Und auch wenn die Pakethierarchie innerhalb der Programmiersprache nicht über eine Unterpaket-Semantik verfügt, so haben doch zumindest die Entwickler bei der Bildung von Unterpaketen häufig eine solche Semantik im Sinn. Ist dies der Fall, so können die negativen Eigenschaften von Zyklen abgeschwächt werden. Es könnte z. B. sein, dass die enge Kopplung der Klassen es sinnlos erscheinen lässt, sie unabhängig voneinander zu testen, zu verteilen, sie separat wiederzuverwenden oder von separaten Teams entwickeln zu lassen (siehe auch meinen Artikel zum Einfluss von Zyklen auf Qualitätsmerkmale).

In der genannten Studie wurde diese Argumentation genutzt, um ein Ranking der "Unerwünschtheit" von Zyklen zu ermitteln. In der schon zuvor vorgestellten Studie "On The Shape of Circular Dependencies in Java Programs" [Dietrich2014] ging man einen Schritt weiter und untersuchte die Häufigkeit des Vorkommens von Zyklen innerhalb von Zweigen der Pakethierarchie. Tatsächlich konnte festgestellt werden, dass ein großer Teil der gefundenen Zyklen sich innerhalb solcher Zweige befindet. Zudem ließ sich beobachten, dass diese Zyklen häufig eine Hub-ähnliche Struktur aufweisen, wobei der zentrale Knotenpunkt des Hubs von einem Eltern-Paket gebildet wird. Dies bestätigt die Vermutung, dass derartige Zyklen aus Umstrukturierungen hervorgegangen sind, die dem obigen Beispiel ähneln.

Schlussfolgerung

Bereits die Betrachtung diverser Zyklus-Formen im vorherigen Artikel ergab, dass Zyklen unterschiedlich problematisch sein können. Je größer Zyklen sind und je weniger regulär sie geformt sind, desto unwahrscheinlicher ist es, dass die Entwickler sie beabsichtigt haben und dass sie keine negativen Auswirkungen entfalten werden. Die Betrachtung der Platzierung von Zyklen innerhalb der Pakethierarchie fügt dieser Unterscheidung einen weiteren Aspekt hinzu. Im folgenden Artikel werde ich einige weitere Eigenschaften von Zyklen beschreiben, welche eine präzisere (ggf. werkzeuggestützte) Beurteilung ermöglichen.

Quellen

[Dietrich2014] - On The Shape of Circular Dependencies in Java Programs, Al-Mutawa H., Dietrich J., Marsland S., McCartin, C., Proceedings ASWEC'14, Preprint (2014)

[Laval2011] - Efficient retrieval and ranking of undesired package cycles in large software systems, Jean-Rémy Falleri, Simon Denier, Jannik Laval, Philippe Vismara, Stéphane Ducasse (2011)