Was ist eigentlich Kopplung?

Funktionseinheiten von Software sollen lose gekoppelt sein. Das ist ein Prinzip, dass wir alle runterbeten können - aber was bedeutet das denn konkret?

Irgendwie scheint es auch schwer einzuhalten, denn die Mehrheit der Softwaresysteme, die ich sehe, folgt ihm eher nicht. Monolithen sind das Gegenteil von loser Kopplung. Da hilft auch kein Einsatz von Interfaces.

image

Also: Was ist (lose) Kopplung und warum ist sie so schwer herzustellen?

Ein Blick in Wikipedia fördert leider nicht wirklich Hilfreiches zu Tage. Danach ist Kopplung…

die Verknüpfung von verschiedenen Systemen, Anwendungen, oder Softwaremodulen, sowie ein Maß, das die Stärke dieser Verknüpfung bzw. der daraus resultierenden Abhängigkeit beschreibt.

Und danach findet sich eine Liste Kopplungsarten, die ich, hm…, akademisch finde. Nicht falsch, aber eben nicht praxistauglich. Zumindest nicht für den Einstieg.

Der Eintrag zu loser Kopplung bringt auch nichts, würde ich sagen. Da steht z.B.

Eine lose Kopplung bedeutet in der Softwarearchitektur, dass Komponenten einer Software nur über wenige Schnittstellen mit anderen Komponenten kommunizieren bzw. von anderen Komponenten abhängig sind.

Wenn es nicht weit her ist mit der losen Kopplung in den heutigen Softwaresystemen, dann ist das kein Wunder, scheint mir. Aus solcher Schwurbelei lassen sich konkrete Maßnahmen nur schwer ableiten.

Ich versuche deshalb mal, den Begriff alltagstauglich zu fassen.

Kopplung konkret

Kopplung ist nötig, wenn Kooperation im weitesten Sinn gewünscht ist. Daran geht nichts vorbei. Sollen zwei Funktionseinheiten - Funktionen, Klassen, Bibliotheken, Services, Anwendungen, Softwaresysteme - miteinander arbeiten, dann müssen sie gekoppelt werden.

Das ist wie bei einer Lokomotive und Waggons. Wenn die Lokomotive Waggons ziehen soll, müssen die an die Lokomotive und untereinander gekoppelt sein, damit sich die Zugkraft überträgt.

Und auch hier ist die Stärke der Kopplung schon ein Thema. Sie braucht ein rechtes Maß: Ist sie zu lose, fällt der Zug [sic!] leicht auseinander. Ist sie zu fest, zerbricht es den Zug z.B. in Kurven.

Die erste Frage an eine Kopplung ist also die nach dem Zweck. Das Fragewort ist Wozu. Bei Lokomotive und Waggons geht es um Kraftübertragung zum Zwecke der Bewegung. Die Lokomotive ist Zugkraftdienstleister für die Waggons.

Die Kopplung im Sinne eines Zwecks ist immer eng, würde ich sagen. Weil das der Sinn einer Kopplung ist.

In allen anderen Belangen jedoch lässt sich die Stärke von Kopplung variieren von eng bis lose.

Hier meine Liste von solchen Belangen. Ich versehe sie alle mit einem Fragewort, um deutlich zu machen, dass wir uns immer wieder fragen sollten, wie stark die einzelnen Kopplungen denn wirklich sein müssen.

  • Wer: Wer ist es, an den eine Funktionseinheit gekoppelt ist? Ist eine Funktionseinheit an eine konkrete Instanz oder Identität einer anderen gekoppelt? Das Prinzip IoC und die Diskussion um Zustand in Servern drehen sich um diesen Kopplungsbelang.
  • Wo: Ist einer Funktionseinheit der “Ort” der anderen bekannt - egal, wie eng sie an eine Instanz gekoppelt ist. “Orte” sind Speicherbereiche, Prozesse oder Geräte. Dieser Belang hat jedoch zwei Seiten: Adresse und Entfernung. Die Adresse bezeichnet einen Platz in einem Adressraum, das kann ein physikalischer Speicher sein oder ein virtueller Raum wie das Internet. Die Diskussion um DI Container, Warteschlangen und Servicebusse drehen sich um diesen Kopplungsbelang. Die Entfernung hingegen sagt etwas darüber aus, wie leicht/schnell die Kommunikation zwischen zwei Orten stattfinden kann. Wenn Kopplungspartner sich nicht über ihre Hauptspeicheradresse kennen, geht es hier um Transportmedien, Protokolle, Kompression oder Caches.
  • Wohin: Wie ist die Kopplung zwischen zwei Funktionseinheiten gerichtet? Ist sie unidirektional oder bidirektional? Wer muss wieviel vom anderen wissen? Die Diskussion um die Vermeidung zirkulärer Referenzen adressiert diesen Belang. Aber auch bei der reaktiven Programmierung bzw. asynchroner Verarbeitung geht es darum.
  • Wann: Wann erwartet eine Funktionseinheit das Ergebnis einer anderen? Oder ist eine Funktionseinheit daran gebunden, wann ihr Kopplungspartner existiert? Darum geht es bei asynchroner Verarbeitung, Event-Driven Architecture und Cloud-Diensten wie ironWorker.
  • Womit: Wie sind die Daten (Parameter, Resultat, globale Daten), aber auch die Dienste strukturiert, auf denen Kopplungspartner arbeiten? Inhaltlich, also in Bezug auf den Zweck (Wozu) gibt es da immer eine enge Kopplung (logische Abhängigkeit). Aber bei der Form gibt es Spielraum. Darum geht es u.a. bei dynamischen Programmiersprachen oder NoSql.
  • Wie: Wieviel weiß eine Funktionseinheit darüber, wie es in ihrem Kopplungspartner aussieht? Kann sie algorithmische oder datenbezogene Details kennen - oder nutzt sie sie gar? Ist sie nicht nur an eine Leistung, sondern auch an die Plattform, auf der die erbracht wird, gekoppelt? Wenn über Entkopplung gesprochen wird, dann meist in dieser Hinsicht. Objektorientierung, Information Hiding, Interfaces: das sind Begriffe, die bei der Diskussion über diesen Belang fallen.

Auf alle W-Fragen zu Belangen der Kopplung kann die Antwort mehr oder weniger spezifisch sein. Je spezifischer aber, desto enger die Kopplung.

Eine bestimmte Instanz an einer bestimmten Adresse in bestimmter Entfernung, die zu einem bestimmten Zeitpunkt vorhanden sein muss und zeitlich in bestimmter Spanne mit ganz bestimmten Strukturen in einer ganz bestimmten Struktur in genau bestimmter Weise arbeitet… an die ist die Kopplung eben sehr, sehr eng.

Oder eben umgekehrt ist die Kopplung lose, wenn die Antworten unbestimmter ausfallen. Wenn Instanzen egal sind, wenn nicht genau gewusst werden muss, wo und in welcher Entfernung sind sie befinden. Wenn der Zeitpunkt ihrer Existenz und ihrer Antwort nicht festgeschrieben sein müssen. Wenn die Datenstrukturen und Aufrufstrukturen nicht in Beton gegossen sind. Und wenn es egal ist, wie im Detail die Leistung erbracht wird.

Wenn Sie dem Prinzip der losen Kopplung folgen wollen, dann stellen Sie sich am besten immer wieder diese Fragen. Bemühen Sie sich, die Antworten möglichst allgemein, offen, locker zu halten. Als Gewinn winken höhere Evolvierbarkeit und bessere Testbarkeit.

Aber auch ein Preis ist zu bezahlen. Lose Kopplung ist eine Form von Flexibilität. Das sehen Sie an der Verbindung zwischen Waggons. Flexibilität jedoch steht im Gegensatz zu Effizienz. Wo Sie lose koppeln, leidet also irgendeine Form von Effizienz. Das könnte die Entwicklungsgeschwindigkeit sein oder die Performance der Software. Das ist nicht zu vermeiden.

Lose Kopplung gibt es also nicht umsonst, sondern nur in einem Trade-off mit anderen Werten. Seien Sie sich derer also bewusst. Und denken Sie nicht nur an heute, sondern auch an morgen und übermorgen.

Deshalb ist für mich der default, im Zweifelsfall eher in lose Kopplung zu investieren, also in Flexibilität, denn in Effizienz. Das scheint mir nachhaltiger.


wallpaper-1019588
Rangordnung Hund und Kind: Wichtige Regeln für Eltern
wallpaper-1019588
#1505 [Session-Life] „Picture my Day“ Day #2024 ~ April
wallpaper-1019588
Mai-Veröffentlichungen von Yomeru im Überblick
wallpaper-1019588
Mai-Veröffentlichungen von TOKYOPOP im Überblick