Lack of Cohesion in Methods, kurz: LCOM, ist eine Metrik, die sich aus den Prinzipen der Single-Responsibility und der Kohäsion (dt. Zusammenhalt) ableitet. Das Ziel in der objektorientierten Softwareentwicklung ist, ein möglichst hohes Maß an Zusammenhalt zu erreichen. Jede Softwareeinheit, im objektorientierten Umfeld also jede Klasse und Methode, soll für genau eine klar umrissene Aufgabe verantwortlich sein. Sie soll eng verwandte Funktionalitäten zusammenfassen. Andererseits soll eine Softwareeinheit keine Funktionalitäten implementieren, die außerhalb ihres Verantwortungsbereichs liegen.
Die LCOM-Metrik versucht nun, den Grad des Zusammenhalts zu quantifizieren. Es gibt mehrere Versionen dieser Metrik. Dieser Artikel befasst sich mit der vierten Version LCOM4, die unter anderem auch in der aktuellen Version des Code-Analyse-Werkzeugs Sonar verwendet wird.
Ähnlich wie bei der Metrik der Zyklomatischen Komplexität, greift man auch bei LCOM4 auf die Graphentheorie zurück. Alle Felder und Methoden einer Klasse werden als Knoten dargestellt. Aufrufe zwischen Methoden und Referenzen auf Felder werden als Kanten dargestellt. Besteht der daraus resultierende Graph aus mehr als einer Komponente, so liegt ein LCOM4-Wert > 1 vor.
In diesem Fall sollte die betroffene Klasse einem Refactoring unterzogen werden, wobei aus jeder der ermittelten Komponenten eine neue Klasse mit einem LCOM4-Wert von 1 erzeugt wird.
Beispiel
Abbildung 1: Zusammenhangsgraph mit zwei Komponenten, d.h. LCOM4-Wert von 2
In Abbildung 1 werden die Zugriffe von Methoden einer Klasse auf ihre Felder dargestellt. Dabei ergeben sich zwei getrennte Komponenten. Das Prinzip der Kohäsion ist verletzt. Die Methode doSomethingEntirelyElse()
nutzt keine Felder, die sie mit den anderen beiden Methoden gemeinsam hätte. Sie nutzt lediglich z
. Diese beiden Elemente könnten auch in einer anderen Klasse angesiedelt sein. Die Methoden doSomething()
und doSomethingElse()
wären von einem solchen Refactoring nicht betroffen.
Sofern es keine weiteren Gründe gibt, die es zwingend erforderlich machen, die Klasse im oben gezeigten Zustand zu belassen, sollte ein Refactoring in Erwägung gezogen werden. Die ohnehin unabhängige Funktionalität von doSomethingEntirelyElse()
wäre dann auch von ihrer Implementierung her von doSomething()
und doSomethingElse()
entkoppelt.
Ergibt die Analyse einen Zusammenhangsgraph wie in Abbildung 2, mit genau einer Komponente, so ist der LCOM4-Wert = 1 und ein Refactoring ist nicht erforderlich.
Abbildung 2: Zusammenhangsgraph mit einer Komponente
Anwendung in der Praxis
Softwaremetriken wie LCOM4 helfen dabei, Kandidaten für ein Refactoring zu ermitteln. Ob man danach wirklich tätig werden muss, sollte man durch eigenständiges und intensives Nachdenken entscheiden. In den allermeisten Fällen ist es sinnvoll, sich nach diesem bewährten Entwurfsmuster zu richten und für einen höheren Grad an Zusammenhalt im Quellcode zu sorgen.
Bei Factory- oder Utility-Klassen lassen sich hohe LCOM4-Werte mitunter selten vermeiden. Also akzeptiert man sie in diesen Fällen, als zu zahlenden Preis für die Vorteile anderer Entwurfsmuster.
Das Ergebnis der konsequenten Auswertung von LCOM4 sollte in erster Linie besserer Quellcode sein und nicht zwangsläufig ein besserer LCOM4-Wert. Das gilt übrigens auch für alle anderen Softwaremetriken.