Codemetriken – Kopplung zwischen Klassen
Die Kopplung zwischen Klassen wird auch als Kopplung zwischen Objekten (Coupling Between Objects, CBO) bezeichnet und wurde ursprünglich durch CK94 definiert. Im Grunde ist die Kopplung zwischen Klassen ein Maß dafür, wie viele Klassen eine einzelne Klasse verwendet. Bei dieser Metrik ist ein hoher Wert ungünstig und ein niedriger Wert in der Regel positiv. Es hat sich gezeigt, dass die Kopplung zwischen Klassen ein präziser Indikator für Softwarefehler ist. Neueste Studien haben gezeigt, dass ein oberer Grenzwert von 9 am effektivsten ist S2010.
Laut Microsoft-Dokumentation misst sie „die Kopplung an eindeutige Klassen durch Parameter, lokale Variablen, Rückgabetypen, Methodenaufrufe, generische oder Vorlageninstanziierungen, Basisklassen, Schnittstellenimplementierungen, für externe Typen definierte Felder und Attributdekorationen. Ein guter Softwareentwurf schreibt vor, dass Typen und Methoden eine hohe Kohäsion und eine geringe Kopplung aufweisen sollten. Eine hohe Kopplung deutet auf einen Entwurf hin, der aufgrund seiner vielen Abhängigkeiten von anderen Typen nur schwierig wiederverwendet und gewartet werden kann.“
Die Konzepte von Kopplung und Kohäsion sind eindeutig miteinander verknüpft. Damit die Diskussion nicht zu sehr vom Thema abschweift, werden wir nicht näher auf die Kohäsion eingehen, sondern nur eine kurze Definition aus KKLS2000 wiedergeben:
Die Modulkohäsion gibt gemäß Yourdon und Constantine Auskunft darüber, „wie eng die internen Elemente eines Moduls miteinander verbunden oder verwandt sind“ (YC79). Ein Modul weist eine starke Kohäsion auf, wenn es genau eine Aufgabe repräsentiert [...], und alle seine Elemente zu dieser einen Aufgabe beitragen. Sie beschreiben die Kohäsion als „ein Attribut des Entwurfs und nicht des Codes und als ein Attribut, das zur Vorhersage von Wiederverwendbarkeit, Wartbarkeit und Änderbarkeit verwendet werden kann.“
Beispiel für die Kopplung zwischen Klassen
Sehen wir uns die Kopplung zwischen Klassen in Aktion an. Erstellen Sie zunächst eine neue Konsolenanwendung und eine neue Klasse mit dem Namen „Person“, die einige Eigenschaften enthält, und berechnen Sie dann sofort die Codemetriken:
Beachten Sie, dass der Wert für die Klassenkopplung 0 lautet, da diese Klasse keine anderen Klassen verwendet. Erstellen Sie nun eine weitere Klasse namens „PersonStuff“ mit einer Methode, die eine Instanz von „Person“ erzeugt und die Eigenschaftenwerte festlegt. Berechnen Sie erneut die Codemetriken:
Sehen Sie, wie der Wert für die Klassenkopplung steigt? Beachten Sie auch, dass der Wert für die Klassenkopplung nur um 1 und nicht weiter ansteigt, unabhängig davon, wie viele Eigenschaften Sie festlegen. Jede Klasse wird nur einmal für diese Metrik gemessen, egal wie oft sie verwendet wird. Sehen Sie außerdem, dass DoSomething()
den Wert 1 aufweist, der Konstruktor PersonStuff()
aber den Wert 0? Derzeit ist kein Code im Konstruktor enthalten, der eine andere Klasse verwendet.
Was würde passieren, wenn Sie Code in den Konstruktor einfügen, der eine andere Klasse verwendet? Sie würden folgendes Ergebnis erhalten:
Der Konstruktor enthält nun eindeutig Code, der eine andere Klasse verwendet, und die Klassenkopplungsmetrik weist auf diese Tatsache hin. Auch hier sehen Sie, dass die Kopplung zwischen Klassen für PersonStuff()
insgesamt 1 und für DoSomething()
ebenfalls 1 lautet. Damit wird angezeigt, dass nur eine externe Klasse verwendet wird, unabhängig vom Umfang des internen Codes, der sie verwendet.
Als Nächstes erstellen Sie eine weitere neue Klasse. Geben Sie dieser Klasse einen Namen, und erstellen Sie einige Eigenschaften darin:
Jetzt nutzen Sie die Klasse in unserer DoSomething()
-Methode innerhalb der PersonStuff
-Klasse und berechnen erneut die Codemetriken:
Wie Sie sehen, steigt der Wert der Klassenkopplung für die Klasse „PersonStuff“ auf 2. Wenn Sie die Klasse genauer betrachten, sehen Sie, dass die DoSomething()
-Methode am stärksten gekoppelt ist, der Konstruktor aber dennoch nur 1 Klasse nutzt. Anhand dieser Metriken können Sie die maximale Gesamtzahl für eine bestimmte Klasse ermitteln und die Details der einzelnen Member einsehen.
Die magische Zahl
Wie bei der zyklomatischen Komplexität gibt es auch hier keinen Grenzwert, der für alle Organisationen gleichermaßen geeignet ist. Allerdings wird in S2010 darauf hingewiesen, dass ein Grenzwert von 9 optimal ist:
„Daher betrachten wir die Schwellenwerte [...] als am effektivsten. Diese Schwellenwerte (für einen einzelnen Member) lauten CBO = 9[...].“ (Hervorhebung hinzugefügt)
Codeanalyse
Eine der Kategorien der Codeanalyse sind Wartbarkeitsregeln. Weitere Informationen finden Sie unter Wartbarkeitsregeln. Bei Verwendung der Legacycodeanalyse enthält der erweiterte Regelsatz für Entwurfsrichtlinien einen Bereich zur Wartbarkeit:
Der Bereich zur Wartbarkeit enthält eine Regel für die Kopplung zwischen Klassen:
Diese Regel gibt bei einer übermäßigen Klassenkopplung eine Warnung aus. Weitere Informationen finden Sie unter CA1506: Vermeiden einer übermäßigen Klassenkopplung.
Quellen
CK94
Chidamber, S. R. und Kemerer, C. F. (1994). A Metrics Suite for Object Oriented Design (IEEE Transactions on Software Engineering, Bd. 20, Nr. 6). Abgerufen am 14. Mai 2011 von der Website der University of Pittsburgh: http://www.pitt.edu/~ckemerer/CK%20research%20papers/MetricForOOD_ChidamberKemerer94.pdf
KKLS2000
Kabaili, H., Keller, R., Lustman, F. und Saint-Denis, G. (2000): Class Cohesion Revisited: An Empirical Study on Industrial Systems (Proceedings of the Workshop on Quantitative Approaches in Object-Oriented Software Engineering). Abgerufen am 20. Mai 2011 von der Website der Université de Montréal: http://www.iro.umontreal.ca/~sahraouh/qaoose/papers/Kabaili.pdf
SK2003
Subramanyam, R. und Krishnan, M. S. (2003). Empirical Analysis of CK Metrics for Object-Oriented Design Complexity: Implications for Software Defects (IEEE Transactions on Software Engineering, Bd. 29, Nr. 4).
S2010
Shatnawi, R. (2010): A Quantitative Investigation of the Acceptable Risk Levels of Object-Oriented Metrics in Open-Source Systems (IEEE Transactions on Software Engineering, Bd. 36, Nr. 2).
YC79
Edward Yourdon und Larry L. Constantine. Structured Design. Prentice Hall, Englewood Cliffs, N.J., 1979.