Am 14. September 2017 haben wir eine überarbeitete Fassung unserer Datenschutzrichtlinie veröffentlicht. Wenn Sie video2brain.com weiterhin nutzen, erklären Sie sich mit diesem überarbeiteten Dokument einverstanden. Bitte lesen Sie es deshalb sorgfältig durch.

Grundlagen der Programmierung: Codemetriken

Klassenkopplung

LinkedIn Learning kostenlos und unverbindlich testen!

Jetzt testen Alle Abonnements anzeigen
Kopplung ist ein wichtiges Qualitätsmerkmal. Der Film erläutert, welche Arten es gibt und wie diese durch die Klassenkopplung repräsentiert werden.
07:03

Transkript

Bei der Bewertung von Code-Qualität ist eine Sache meist entscheidend und zwar der Grad der Kopplung beziehungsweise die Abhängigkeiten. Wir betrachten, was Kopplung ist und wie es sich in der Metrik der "Klassen-Kopplung" niederschlägt. Grundsätzlich ist es so, dass wir immer Code-Bestandteile betrachten. Die Code-Bestandteile, das können Methoden sein, das können Klassen sein, das können Klassen-Member sein, Name Spaces, Assemblies und so weiter und so fort. Diese werden häufig als Rechtecke dargestellt und wir haben hier jetzt einen Code-Bestandteil A. A hat Abhängigkeiten zu anderen Code-Bestandteilen, gezeigt durch einen offenen Pfeil. Diese Code-Bestandteile haben wiederum Abhängigkeiten zu anderen Bestandteilen und so weiter und so fort, so lange, bis es eben keine Nachfolger mehr gibt, in unserem Fall, also beispielsweise bei X. A ist damit transitiv abhängig von X. Und die Kopplung gibt nun den Grad der Abhängigkeit an. Wie stark ist A beispielsweise von X abhängig? Also, wie viele Zugriffe gibt es darauf? Gibt es Möglichkeiten zu entkoppeln? Wichtig ist dabei eben, wieviele Abhängigkeiten es gibt. Und bei der Betrachtung der Abhängigkeiten gibt es zwei Möglichkeiten beziehungsweise zwei unterschiedliche Arten von Abhängigkeiten. Da hätten wir zum einen die etwas seltener betrachtete "Afferent Coupling". Dies bezeichne ich auch als die "Eingehende Kopplung" von X. Wir analysieren also, welche Bestandteile nutzen X. Tatsächlich direkte Nutzung gibt es in diesem Beispiel nur zwei, indirekte Nutzung gibt es aber ziemlich viele. Das Thema "Eingehende Abhängigkeit" ist dabei vielleicht nicht korrekt übersetzt von Afferent Coupling, aber es lässt sich leichter merken, weil man halt nur die Richtung der Pfeile betrachten muss. Afferent Coupling sagt dabei aus, wie stark andere Bestandteile betroffen sind, wenn es zu maßgeblichen Änderungen am betrachteten Bestandteil kommt. Also, welche Bestandteile können insgesamt davon betroffen sein, wenn ich jetzt bei X beispielsweise die öffentliche Schnittstelle ändere? Häufig sind davon die direkten Vorgänger betroffen. Wenn ich aber das Verhalten von X ändere, dann muss man auch die indirekten Abhängigkeiten betrachten, weil ja alle vorangegangenen Bestandteile, alle Bestandteile, die X nutzen, X genau deshalb nutzen, weil sie sich davon ein bestimmtes Verhalten erwarten. Gegenüber dem Afferent Coupling gibt es noch das "Efferent Coupling". Klingt nahezu gleich, deswegen sage ich das im Deutschen immer als "Ausgehende Kopplung". Es sind die Kopplungen beziehungsweise es sind die Abhängigkeiten, die von A ausgehen, die dadurch entstehen, dass A etwas anderes nutzt. A wird demnach automatisch davon betroffen, welche Änderungen stattfinden bei seinen direkten Nachbarn beziehungsweise bei den indirekten Bestandteilen, die er nutzt, so ähnlich wie vorhin mit X, nur dass A halt von mehr Veränderung betroffen ist als X. Bei X ist es ja, dass ich nur die Stelle ändere und das interessiert X selbst erst einmal nicht. Bei A ist es so, dass A eindeutig davon betroffen ist, wenn X sich ändert beziehungsweise wenn sich irgendwelche anderen genutzten Teile [unverständlich]. Aus diesem Grund beziehen sich viele der Analysen vor allem auf das Efferent Coupling und nicht so sehr auf das Afferent Coupling, also mehr auf die Ausgehende Kopplung als die Eingehende Kopplung. Ein Beispiel für diese Ausgehende Kopplung ist das "Class Coupling" beziehungsweise die "Klassen-Kopplung". Hierbei wird betrachtet, wieviele Bestandteile, wieviele Typen von einem anderen Typen genutzt werden beziehungsweise von einem Bestandteil. Wir haben hier eine Methode "Initialize". Diese Initialize-Methode macht ziemlich viel. Sie setzt zunächst einen intern konfigurierten Workflow zurück. Danach liest sie einen Workflow aus einer XML-Datei, um anschließend den neuen Workflow entsprechend aufzubauen. Wir sehen schon, dass dieses Initialize ziemlich komplex ist, weil es 18 Abhängigkeiten hat. Die Abhängigkeiten weisen uns also ein Stück weit darauf hin, dass wir hier eventuell zu viel Komplexität haben, dass wir zu viele Dinge zeitgleich machen. Das "Single Responsibility Principle" aus dem Clean Code sagt deshalb aus, dass eine Sache nur einen Grund haben sollte, sich zu ändern, dass eine Sache nur eine einzige Aufgabe haben sollte. Wir können einem hohen Grad der Kopplung demnach begegnen, indem wir unsere Code-Bestandteile aufspalten, indem wir sie klein machen. Das sorgt dafür, dass wir dann höchstwahrscheinlich nur noch an bestimmten Stellen einen hohen Grad der Kopplung haben, während der Rest verhältnismäßig lose gekoppelt ist. Hier ist das Ergebnis, wenn wir unsere Initialize-Methode aufspalten: Wir haben dann eine Methode "LoadWorkflow" und die macht nichts anderes, als eben den Workflow zu laden. Die anderen Methoden wurden entsprechend aufgespalten und dadurch ist unsere Initialize-Methode jetzt recht klein. Sie hat nur noch ein "Class Coupling" von 3, weil sie kaum noch andere Typen verwendet. Unsere eigene Methode "LoadWorkflow" ist immer noch recht groß. Sie hat 15 Klassen, die sie nutzt. Wenn Sie jetzt einfach nur den Quellcode durchgehen, dann wird es Ihnen tatsächlich sogar etwas schwerfallen, all diese 15 Typen zu finden. Der Grund, warum ich das mit aufgenommen habe, ist, um zu zeigen, wie stark auch die indirekte Kopplung sein kann, also wieviele Schnittstellen wir als solche gar nicht wahrnehmen, durch Rückgabetypen, die wir sofort weiter verwenden, durch Parameter oder durch die Verkettung von Befehlen, wie zum Beispiel "availableWorkflowModels. Value.FirstOrDefault". Da stecken schon eine ganze Menge unterschiedliche Typen drin, die uns einfach nicht auffallen, weil wir so eine Kette von Befehlen geschrieben haben. Eine Möglichkeit zur Entkopplung wird gerne bei "Dependency Injection" und Ähnlichem verwendet. In dem Fall nutzt man statt der konkreten Implementierung A eine Schnittstellendefinition, eine abstrakte Schnittstellendefinition. Das kann eine abstrakte Klasse sein oder eben ein Interface. Und dann wird zunächst nur über diese Schnittstelle auf die Funktionalität zugegriffen. Das Zusammenfassen von Implementierung und Schnittstelle passiert dann erst zur Laufzeit. Und dann spricht man eben von "Später Bindung". So kann man komplette Subsysteme, komplette Komponenten austauschbar gestalten und sich von deren Funktionalität beziehungsweise von deren Verhalten ein Stück weit entkoppeln. Es treibt vor allem aber auch die Abhängigkeiten innerhalb unserer Anwendung herunter.

Grundlagen der Programmierung: Codemetriken

Lernen Sie Methoden, Prinzipien und Werkzeuge kennen, mit deren Hilfe Sie die Qualität Ihrer Software dauerhaft sicherstellen können.

1 Std. 43 min (20 Videos)
Derzeit sind keine Feedbacks vorhanden...
 
Exklusiv für Abo-Kunden
Erscheinungsdatum:25.04.2017

Dieser Online-Kurs ist als Download und als Streaming-Video verfügbar. Die gute Nachricht: Sie müssen sich nicht entscheiden - sobald Sie das Training erwerben, erhalten Sie Zugang zu beiden Optionen!

Der Download ermöglicht Ihnen die Offline-Nutzung des Trainings und bietet die Vorteile einer benutzerfreundlichen Abspielumgebung. Wenn Sie an verschiedenen Computern arbeiten, oder nicht den ganzen Kurs auf einmal herunterladen möchten, loggen Sie sich auf dieser Seite ein, um alle Videos des Trainings als Streaming-Video anzusehen.

Wir hoffen, dass Sie viel Freude und Erfolg mit diesem Video-Training haben werden. Falls Sie irgendwelche Fragen haben, zögern Sie nicht uns zu kontaktieren!