Mittwoch, 12. November 2014

Einfachheit der Struktur - Kopplung

Der vorherige Blogartikel, der den Zusammenhang zwischen Einfachheit und Kohäsion untersucht hat, führte Kopplung bereits als ein zur Kohäsion komplementäres Konzept ein. Der vorliegende Artikel untersucht nun die Entstehung hoher Kopplungsgrade etwas genauer. Insbesondere werden die folgenden beiden Aspekte betrachtet:
  • Richtige Grenzziehung: Während das Konzept der Kohäsion eher die richtige Größe von Software-Elementen höherer Ebenen in den Vordergrund stellt, liegt der Schwerpunkt des Konzepts der Kopplung auf den richtigen Grenzen dieser Elemente. 
  • Stärke verschiedener Kopplungsarten: Des weiteren kann zwischen verschiedenen Arten der Kopplung unterschieden werden, die hinsichtlich ihrer Stärke unterschiedlich bewertet werden müssen.

1. Die richtigen Grenzen ziehen

Warum der Kopplungsgrad einer Ebene davon abhängt, ob die Grenzen von Software-Elementen höherer Ebenen richtig gezogen werden, soll wieder an einem Beispiel veranschaulicht werden.
Wie im Artikel Einfachheit der Struktur - Grundlagen ausgeführt, ändert sich durch die Gruppierung auf höherer Ebene nichts an den Relationen der darunterliegenden Ebenen. In diesem Beispiel wurden einfach die drei roten Elemente inklusive ihrer bestehenden Relationen in die linke Einheit verschoben. Berechnen wir die Kohäsion eines Elements E nach dem vereinfachten Modell von [Wang2007], d. h. ohne Berücksichtigung der durchschnittlichen Distanz der Subelemente, gemäß der Formel
und berücksichtigen, dass die Kopplung zur Kohäsion in diesem Modell komplementär ist, d. h. Kohäsion + Kopplung = 1, so ergeben sich die folgenden Kohäsions- und Kopplungswerte:

Kohäsion Linkes Element Rechtes Element
Vorher 94,44% 95,00%
Nachher 86,96% 81,25%


Kopplung Linkes Element Rechtes Element
Vorher 5,56% 5,00%
Nachher 13,04% 18,75%

Aus der Sicht der Kohäsion könnte man noch von einem geringen Effekt sprechen. Der Kopplungsgrad hingegen erhöht sich hier um das Zwei- bis Dreifache. Berücksichtigen wir, dass sich gemäß der Studie [Kemerer2005] insbesondere die Kombination geringer Kohäsion und starker Kopplung negativ auf die Komplexität der Software auswirkt, so fällt der negative Effekt dieser falschen Grenzziehung durchaus ins Gewicht.

Dieser Fall mag trivial erscheinen. Im Entwicklungsalltag kann es aber durchaus sein, dass Lösung (2) durch Hinzufügen neuer Elemente allmählich entsteht und dass die Möglichkeit einer Restrukturierung zu Lösung (1) irgendwann erkannt und durchgeführt werden muss. Insbesondere wenn weitere Elemente vom rechten Struktur-Element abhängen, kann dies zu einer Kette von Folgeaufwänden führen, auf die man gerne verzichten würde. Auf Dauer entstehen dann aber hohe Kopplungsgrade zwischen den Elementen der jeweiligen Struktur-Ebene.

2. Die Art der Kopplungen

Im Einzelfall kann die Entscheidung zwischen zwei Grenzziehungen schwerfallen. Ein vereinfachtes Kohäsions-/Kopplungsmodell wie das von Wang, das nur auf der Zahl der internen und externen Relationen beruht, ist dann ggf. nicht mehr in der Lage, zwei Lösungen ausreichend deutlich voneinander zu unterscheiden. In das Kohäsionsmodell hatten wir daher bereits den Faktor Nähe eingeführt, um das Konzept der Zusammengehörigkeit, das der Kohäsion zu Grunde liegt, in die Betrachtung aufzunehmen. Nun gilt es, auch das Kopplungsmodell noch etwas zu verfeinern.

Verschiedene Autoren unterscheiden unterschiedliche Kopplungsarten. Es wäre nun hilfreich, die Kopplungsart in der Abwägung zu berücksichtigen. So schreibt z. B. Balzert:
"Um eine Kopplung zu minimieren, muss die jeweils schwächste Kopplungsart jeder Komponente angestrebt werden." [Balzert1998]
Balzert selbst schlägt folgende Unterscheidungen für Kopplungen auf der Ebene der Funktionen und Daten-Objekte vor:
  • Kopplungsmechanismus
    • Aufruf
    • Verzweigung (goto)
  • Schnittstellenbreite
    • Anzahl der Parameter
    • Datentyp der Parameterelemente (elementar oder strukturiert)
  • Kommunikationsart 
    • Datenkopplung
    • Steuerungskopplung
Eine andere Unterteilung wird in [Aloysius2012] vorgenommen, wobei das umfassende Element jeweils als module bezeichnet wird und ein objektorientiertes Szenario vorausgesetzt wird:
  • Control Coupling: "Passing control flags between modules ...".
  • Global Data Coupling: "Two or more modules share the same global data structures."
  • Internal Data Coupling: "One module directly modifies local data of another module."
  • Data Coupling: "Output from one module is the input of another ...".
  • Lexical Content Coupling: "Some or all the contents of one module are included in the contents of another." (Alle Zitate dieser Liste gemäß [Aloysius2012].)
Eine bereits über 50 Jahre alte Einteilung stammt von Glenford J. Myers [Myers1974]. Hier stammt die entsprechende Zusammenfassung aus dem Wikipedia-Artikel zum Thema Kopplung:
  • "Content coupling: Das Modul verlässt sich auf die konkrete inhaltliche Umsetzung eines anderen Moduls bzw. modifiziert die internen Daten des anderen. Diese sehr starke Art der Kopplung sollte unbedingt vermieden werden.
  • Common coupling: Zwei Module kommunizieren über gemeinsame globale Daten.
  • External coupling: Zwei Module kommunizieren über einen extern vorgegebenen Mechanismus; beispielsweise eine bestimmte Datei mit definiertem Aufbau.
  • Control coupling: Ein Modul nimmt Einfluss auf den Kontrollfluss eines anderen; beispielsweise durch einen Parameter, der die Art der konkreten Aktion spezifiziert. Hierbei ist zu unterscheiden ob der Kontrollparameter ein Aufrufparameter oder ein Rückgabewert ist. Ersteres ist zu vermeiden, letzteres ist manchmal nicht zu ändern. Somit bildet die Kontrollkopplung die Grenze zwischen den „guten“ schwachen und den „schlechten“ starken Kopplungen.
  • Stamp coupling: Zwei Module kommunizieren über eine komplexe Datenstruktur, von der aber nur ein Teil verwendet wird.
  • Data coupling: Zwei Module kommunizieren über elementare Daten, beispielsweise einfache Parameter." [Url:Wikipedia:Kopplung]
Grundsätzlich können wir je nach Betrachtungsgegenstand auch ganz andere Einteilungen der Kopplungsarten vornehmen. Dies kann jedoch nicht der Anspruch dieses Artikels sein. An dieser Stelle sollte jedoch klar geworden sein, dass Kopplungen sich in ihrer Art unterscheiden und dass von der Kopplungsart auch die tatsächliche Stärke jeder einzelnen Kopplung abhängt.

[Aloysius2012] variieren in einem Experiment die von ihnen unterschiedenen Kopplungsarten und ermitteln auf diese Weise kognitive Gewichte, welche die Stärke der Kopplung widerspiegeln sollen. Wir können diesen Ansatz auf beliebige Kopplungsarten verallgemeinern und setzen zu diesem Zweck voraus, dass jede in einem konkreten System gefundene Kopplung einer Kopplungart zugewiesen werden kann, über die ihr ein entsprechendes Gewicht zuzuordnen ist. Dann können wir das folgende verfeinerte Kopplungsmodell angeben:
Bei der Bildung von Elementen auf höheren Struktur-Ebenen müssen die Grenzen also möglichst so gezogen werden, dass starke Kopplungsarten in das Innere der Elemente verschoben werden, während Kopplungen zwischen den Elementen möglichst schwach sein sollten.

3. Andere Kopplungsmodelle

Analog zur Betrachtung der Kohäsion mache ich an dieser Stelle deutlich, dass zahlreiche andere Kopplungsmodelle existieren und verweise auf die entsprechende Literatur (bspw. [Fenton2014], [Sneed2010] oder [Diederichs2005]). Es ist daher für die weitere Betrachtung sinnvoll, die Voraussetzungen explizit zu machen, die wir für Kopplungsmodelle allgemein unterstellen:
  1. Wir haben Kopplung bislang (gemäß dem Modell von Wang) als eine Eigenschaft einzelner Software-Elemente aufgefasst. Wir setzen voraus, dass sich aus den Ausprägungen der Kopplungen der einzelnen Software-Elemente eine Ausprägung der Gesamtkopplung auf System-Ebene ermitteln lässt. Ich nenne diese den Kopplungsgrad des Systems. Wäre dies nicht möglich, so könnten wir uns bei der Minimierung von Kopplungen einzelner Elemente eines Systems nicht sicher sein, ob wir nur lokale Optimierungen vornehmen, die ggf. zu Lasten des Gesamtsystems gehen. Kopplung wäre dann als Eigenschaft unbrauchbar, um Entscheidungen auf System-Ebene zu treffen.
  2. Der Kopplungsgrad zweier verschiedener Systeme S1 und S2 lässt sich vergleichen, d. h. für zwei beliebige Systeme S1 und S2 lässt sich feststellen, ob der Kopplungsgrad von S1 höher, gleich oder niedriger ist. Wäre dies nicht möglich, so würde der festgestellte oder vorhergesagte Kopplungsgrad zweier Lösungen keinen Beitrag zur Entscheidungsfindung zwischen verschiedenen Lösungen leisten können.
  3. Der Kopplungsgrad eines gegebenen Systems bewegt sich zwischen einem Minimum und einem Maximum. Die Zerlegung eines endlichen Systems in Elemente höherer Ebenen kann nicht zu einem unendlich großen Kopplungsgrad führen.

4. Quellen

[Aloysius2012] - Coupling Complexity Metric: A Cognitive Approach, A. Aloysius, L. Arockiam (2012)

[Balzert1998] - Lehrbuch der Softwaretechnik, Helmut Balzert (1998)

[Diederichs2005] - Komplexitätsreduktion in der Softwareentwicklung, Henner Diederichs (2005)

[Fenton2014] - Software Metrics: A Rigorous and Practical Approach, Third Edition, Norman Fenton (2014)

[Kemerer2005] - The Structural Complexity of Software: An Experimental Test - David P. Darcy, Chris F. Kemerer, Sandra A. Slaughter, James E. Tomayko (2005)  

[Myers1974] - Reliable Software through Composite Design, Glenford J. Myers (1974)

[Sneed2010] - Software in Zahlen - Die Vermessung von Applikationen, Harry M. Sneed, Richard Seidl, Manfred Baumgartner (2010)

[Url:Wikipedia:Kopplung] - Wikipedia-Artikel "Kopplung (Softwaretechnik)" (Stand 12.11.2014)

[Wang 2007] - Software Engineering Foundations - A Software Science Perspective, Wang, Yingxu (2007)