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.
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.
2 Kommentare:
"Und danach findet sich eine Liste Kopplungsarten, die ich, hm…, akademisch finde. Nicht falsch, aber eben nicht praxistauglich."
Dieser Post fällt aber leider in die gleiche Kategorie - in der Praxis hilft er mir kein Stück weiter.
Es fehlen einfach konkrete Verhaltensregeln, je allgemeiner und abstrakter die Beschreibung wird, desto praxisuntauglicher wird sie zum gleichen Zeitpunkt.
Wenn Softwareentwicklung dem Beispiel des Handwerks folgen soll, dann müssen konkrete Verhaltensregeln her. Ein Maurer interessiert sich nicht für den Ursprung der Gravitation, oder der genauen Bestimmung von Gravitationskräften und was die resultierenden Kräftevektoren sind. Er hängt ein Lot auf, oder benutzt die Wasserwaage und "gets the job done".
Schade, dass für dich die W-Fragen mit den Beispielen für dich kein Stück konkreter sind.
Die konkreten Verhaltensregeln allerdings kannst du nicht unbedingt von einem Artikel mit der Überschrift "Was ist eigentlich Kopplung" erwarten. Dafür müsste sie eher lauten "Tipps & Tricks zur Vermeidung von enger Kopplung" oder so.
Das sind ja eh die beliebtesten Postings, die mit "Tipps & Tricks" überschrieben werden. Alle wollen ja ganz schnell Abhilfe fürs Handwerk. Tun, machen, wegschaffen - nicht so gern nachdenken und verstehen.
Verständlich - nur leider sind so weder Pyramiden noch Kölner Dom entstanden. Und schon gar nicht der Eiffelturm oder der Burj Al Arab.
Auch wenn da Handwerker mitgearbeitet haben mit Wasserwaage und Lot bzw. ihren modernen Pendants, sind diese Bauwerke zunächst einmal Leistungen von Ingenieuren. Und die interessieren sich sehr wohl für Gravitation und andere Kräfte im Zusammenspiel mit unterschiedlichen Materialien.
Wenn du intuitiv genauso mit den Kräften in der Software umgehst, wie ein mittelalterlicher Handwerker mit Gravitation und Reibung, dann können wir gern wieder über die Reduktion der Softwareentwicklung auf das Handwerk reden. Einstweilen glaube ich jedoch daran, dass mehr Nachdenken und Hintergrundwissen und Ingenieursarbeit nötig ist.
Kommentar veröffentlichen