Read in English · Leer en español · Lire en français
Abschnitt 3.6 von 3.8 · Mittelstufe · 22 Min. Lesezeit
Connascence: ein feineres Maß für Kopplung
Videolektion
5 Min. · auf Englisch gesprochen, mit UntertitelnNur anhören (Audio)
Transkript lesen
Kopplung sagt Ihnen, dass zwei Teile verbunden sind. Connascence sagt Ihnen, wie, wie riskant das ist und welches Refactoring es sicherer machen würde. In dieser Lektion lernen Sie ihre Formen kennen und die drei Arten, sie zu beurteilen.
Wenn zwei Freunde verabreden, sich am üblichen Ort zur üblichen Zeit zu treffen, bindet sie eine Absprache. Niemand sonst kann sie sehen. Und ändert einer von ihnen den Plan, muss der andere es erfahren. Software ist voll von solchen Absprachen: Namen, die Reihenfolge von Werten, was eine Zahl insgeheim bedeutet, welcher Schritt zuerst geschehen muss. Connascence ist eine Methode, sie aufzulisten, das Risiko jeder einzelnen zu beurteilen und die riskanten schwächer, sichtbarer oder näher beieinander zu machen.
Das Wort kommt aus dem Lateinischen für „zusammen geboren“, und Meilir Page-Jones führte es 1992 ein. Zwei Elemente sind connascent, wenn eine Änderung am einen eine Änderung am anderen erfordern würde, damit das System korrekt bleibt. Die Elemente können alles Mögliche sein: eine Funktion und ihre Aufrufer, ein Producer und die Consumer seiner Nachrichten, eine Datenbankspalte und jeder Bericht, der sie liest.
Statische Formen lassen sich durch Lesen des Quellcodes finden. Die schwächste ist die Connascence des Namens: Ein Aufrufer und eine Funktion sind sich über deren Namen einig. Umbenennen ist mechanisch, und Werkzeuge finden jede Verwendung. Connascence des Typs: Beide Seiten sind sich über einen Typ einig, etwa eine Liefergebühr in ganzen Pence. Typprüfer und Schemas machen sie sichtbar. Connascence der Bedeutung: Beide sind sich einig, was ein Wert bedeutet, etwa dass Status vier „Fahrer zugewiesen“ heißt. Solche magischen Werte sind für Werkzeuge unsichtbar. Connascence der Position: Die Reihenfolge von Werten ist wichtig, wie bei Funktionsargumenten oder den Spalten einer Datei. Und Connascence des Algorithmus: Beide Seiten müssen etwas auf dieselbe Weise berechnen, etwa dieselbe Prüfsumme.
Dynamische Formen zeigen sich erst zur Laufzeit, daher sind sie schwerer zu finden und meist stärker. Connascence der Ausführung: Die Reihenfolge der Schritte ist wichtig. Die Zahlung muss autorisiert sein, bevor das Restaurant benachrichtigt wird. Connascence des Timings: Es ist wichtig, wann etwas geschieht. Eine Fahrer-App, die nach fünf Sekunden aufgibt, während die Disposition bis zu acht braucht, wird scheitern. Connascence des Werts: Mehrere Werte müssen sich gemeinsam ändern. Halten Frontend und Backend jeweils die Liste der Liefergebiete, müssen die beiden Listen immer übereinstimmen. Und Connascence der Identität: Elemente müssen sich auf genau dasselbe Ding beziehen, etwa zwei Module, die in einer Datenbanktransaktion schreiben.
Jedes Auftreten lässt sich auf drei Arten beurteilen. Die Stärke beschreibt, wie schwer die Form zu finden und zu ändern ist. Name ist schwach, Bedeutung stärker, und Timing und Identität sind am stärksten. Die Lokalität beschreibt, wie nah die Elemente beieinander liegen. Positionsargumente zwischen zwei privaten Hilfsfunktionen in einer Datei sind harmlos. Positionsfelder in einer Nachricht zwischen Teams sind gefährlich. Der Grad beschreibt, wie viele Elemente sie teilen. Kommt Statuscode drei an achtundzwanzig Stellen vor, die drei Teams gehören, bedeutet eine Änderung seiner Bedeutung achtundzwanzig koordinierte Änderungen. Daraus ergeben sich drei Schritte. Schwächen Sie die Form ab, etwa indem Sie einen magischen Wert durch eine benannte Konstante ersetzen. Rücken Sie stark verbundene Elemente näher zusammen. Oder leiten Sie eine gemeinsame Konvention über eine einzige Definition, um ihren Grad zu verringern.
Dieses Raster fasst es zusammen. Die Formen reichen von der schwächsten links bis zur stärksten rechts, und die Entfernung wächst von oben nach unten. Innerhalb einer Funktion ist jede Form akzeptabel, weil jeder, der eine Seite ändert, die andere sehen kann. Über Services hinweg sind nur Name und Typ gesund: die Absprachen, die ein veröffentlichtes Schema explizit macht. Alles Stärkere ist korallenrot: Refaktorieren Sie es zu einer schwächeren Form, oder rücken Sie die Elemente näher zusammen. Und teilen zwei Services Connascence des Werts oder der Identität, liegt die Grenze wahrscheinlich an der falschen Stelle. Einer sollte die Daten besitzen, oder die beiden sollten ein Service sein.
Hier ein ausgearbeitetes Beispiel aus einer Fahrdienst-App. Ihre Buchungsfunktion ist auf acht Positionsargumente angewachsen: ein Fahrgast, vier Koordinaten, eine Zahl, true und null. Vertauscht man Abhol- und Zielkoordinaten, besteht sie trotzdem die Typprüfung und schickt den Fahrer stillschweigend an den falschen Ort. Das ist Connascence der Position. Zwei bedeutet ein großes Fahrzeug, true heißt mit Karte zahlen, und null heißt sofort buchen. Das ist Connascence der Bedeutung. Und es gibt einunddreißig Aufrufstellen in drei Komponenten. Das Refactoring erfolgt in Schritten. Führen Sie einen Location-Typ und Schlüsselwortargumente ein. Ersetzen Sie die magischen Werte durch benannte. Fassen Sie dann alles in einem Booking-Request-Objekt zusammen. Das Verhalten hat sich nicht geändert. Aber aus starken, unsichtbaren Absprachen sind schwache Absprachen über Name und Typ geworden, die Typprüfer und Editor verifizieren können.
Der vollständige Abschnitt enthält eine Tabelle aller neun Formen mit Wegen, jede abzuschwächen, und einen genaueren Blick auf Connascence zwischen Services. Als Nächstes betrachten wir in Abschnitt drei Punkt sieben das Gesetz von Conway. Bis gleich.
Was Sie wissen müssen
- Zwei Elemente sind connascent, wenn eine Änderung am einen eine Änderung am anderen erfordern würde, damit das System korrekt bleibt; Meilir Page-Jones führte die Idee 1992 ein.
- Statische Formen (Name, Typ, Bedeutung, Position, Algorithmus) sind im Quellcode sichtbar; dynamische Formen (Ausführung, Timing, Wert, Identität) zeigen sich erst zur Laufzeit und sind im Allgemeinen stärker.
- Die Stärke beschreibt, wie schwer eine Form zu finden und zu ändern ist, die Lokalität, wie weit die Elemente voneinander entfernt sind, und der Grad, wie viele Elemente die Absprache teilen.
- Wandeln Sie starke Formen in schwächere um, halten Sie starke Connascence lokal und verringern Sie den Grad, indem Sie eine Konvention über eine einzige Definition oder einen einzigen Eigentümer leiten.
- Werden Positionsparameter durch benannte Parameter und magische Werte durch benannte Aufzählungen ersetzt, werden aus starken, unsichtbaren Absprachen schwache, die Werkzeuge prüfen können.
- Zwischen Services sind nur schwache Formen wie Name und Typ in einem veröffentlichten Schema gesund; Connascence von Wert oder Identität zwischen Services weist auf eine falsch gezogene Grenze hin.
Warum Kopplung ein feineres Vokabular braucht
Abschnitt 3.2 hat Kopplung mit den Stufen aus dem Structured Design (Inhalts-, globale, externe, Steuerungs-, Datenstruktur- und Datenkopplung) und mit den verteilten Formen beschrieben, die zwischen Services eine Rolle spielen. Diese Stufen ordnen ein, wie Module verbunden sind. Weniger sagen sie zu zwei Fragen, vor denen Entwicklungsteams täglich stehen: Wie schmerzhaft wird eine Änderung, und welches Refactoring würde den Schmerz verringern? Connascence beantwortet beide.
Connascence (lateinisch etwa „zusammen geboren“) wurde von Meilir Page-Jones 1992 in einem Artikel in den Communications of the ACM, „Comparing techniques by means of encapsulation and connascence“, eingeführt und in seinem Buch What Every Programmer Should Know About Object-Oriented Design (Dorset House, 1995) ausgearbeitet, später überarbeitet als Fundamentals of Object-Oriented Design in UML (1999). Seine Definition ist einfach: Zwei Elemente sind connascent, wenn irgendeine Änderung am einen eine Änderung am anderen erfordern würde, damit das System korrekt bleibt. Die Elemente können alles Mögliche sein: zwei Funktionen, eine Funktion und ihre Aufrufer, ein Producer und die Consumer seiner Nachrichten, eine Datenbankspalte und jeder Bericht, der sie liest.
Zwei Eigenschaften machen die Idee für Architekten nützlich. Erstens gibt es Connascence in benannten Formen, die sich nach Stärke ordnen lassen, sodass man nicht nur sagen kann „diese sind gekoppelt“, sondern „diese sind über die Position gekoppelt, was schlimmer ist als eine Kopplung über den Namen, und so wandelt man das eine ins andere um“. Zweitens hat sie zwei weitere Dimensionen, Lokalität und Grad, die zeigen, ob eine bestimmte Form an ihrer Stelle akzeptabel ist.
Statische Formen: im Code sichtbar
Statische Connascence lässt sich durch Lesen des Quellcodes finden, oft mit Werkzeugen, ohne das Programm auszuführen. Von der schwächsten zur stärksten, in der am häufigsten genannten Reihenfolge:
Connascence des Namens: Elemente müssen sich über einen Namen einig sein. Ein Aufrufer verwendet calculate_tax; ein JSON-Consumer liest customer_id. Es ist die schwächste Form, weil Umbenennen mechanisch ist und Werkzeuge jede Verwendung finden.
Connascence des Typs: Elemente müssen sich über einen Typ einig sein. Eine Funktion erwartet eine ganze Zahl von Pence; die Übergabe eines Floats läuft in Python durch, verfälscht aber das Ergebnis. Typprüfer und Schemas machen sie sichtbar.
Connascence der Bedeutung (oder Konvention): Elemente müssen sich darüber einig sein, was ein Wert bedeutet. Status 3 bedeutet „versandt“; -1 bedeutet „nicht gefunden“; eine leere Zeichenkette bedeutet „Standardwert verwenden“. Solche magischen Werte sind für Werkzeuge unsichtbar: Nichts verbindet die 3 im Lagercode mit der 3 im E-Mail-Service.
Connascence der Position: Elemente müssen sich über die Reihenfolge von Werten einig sein. create_user("Ann", "Smith", "ann@example.com") hängt von der Parameterreihenfolge ab; eine CSV-Datei hängt von der Spaltenreihenfolge ab; ein Tupel (lat, lon) bricht stillschweigend, wenn jemand (lon, lat) annimmt, wie es GeoJSON tut.
Connascence des Algorithmus: Elemente müssen sich über einen Algorithmus einig sein. Sender und Empfänger eines Webhooks müssen dieselbe HMAC-Signatur berechnen; Client und Server müssen dasselbe Passwort-Hashing-Verfahren oder dieselbe Prüfsumme anwenden; jeder Service, der nach Kunde routet, muss dieselbe Hashfunktion verwenden, um einen Shard auszuwählen.
Dynamische Formen: erst zur Laufzeit sichtbar
Dynamische Connascence hängt davon ab, wie sich das System zur Laufzeit verhält, daher ist sie schwerer zu finden und meist stärker.
Connascence der Ausführung: Die Reihenfolge der Ausführung ist wichtig. Eine Verbindung muss geöffnet werden, bevor Daten gesendet werden; begin() muss vor commit() kommen; eine Bestellung muss angelegt sein, bevor ihre Zahlung eingezogen wird.
Connascence des Timings: Der Zeitpunkt der Ausführung ist wichtig. Das Timeout eines Clients muss länger sein als die normale Verarbeitungszeit des Servers; ein Test, der zwei Sekunden schläft, hofft, dass ein asynchroner Job fertig ist; zwei Threads liefern sich ein Wettrennen um die Aktualisierung eines Kontostands.
Connascence des Werts: Mehrere Werte müssen sich gemeinsam ändern, meist wegen einer Invariante. Die Liste gültiger Ländercodes im Web-Frontend und im Backend muss übereinstimmen; die Summe einer Bestellung muss der Summe ihrer Positionen entsprechen; Soll und Haben einer Buchung müssen ausgeglichen sein.
Connascence der Identität: Elemente müssen sich auf dieselbe Entität beziehen, nicht nur auf eine gleiche. Zwei Repositories müssen dieselbe Datenbanktransaktion teilen, damit ihre Schreibvorgänge atomar sind; zwei Komponenten müssen in dieselbe Queue-Instanz veröffentlichen, nicht in zwei Queues mit gleicher Konfiguration.
Page-Jones benannte auch die Gegenbeziehung, die Contranascence: Elemente, die sich unterscheiden müssen, etwa zwei Klassen in einem Namensraum, die nicht denselben Namen tragen dürfen, oder zwei Services, die nicht denselben Port verwenden dürfen. Für sie gelten dieselben Regeln.
Die neun Formen mit je einem Beispiel
| Form | Art | Beispiel in einer Essensliefer-App | Typischer Weg, sie abzuschwächen |
|---|---|---|---|
| Name | Statisch | Der Bestellservice ruft restaurant.get_menu() auf | Bereits die schwächste Form; Namen aussagekräftig halten |
| Typ | Statisch | Liefergebühr als ganze Zahl in Pence übergeben, nicht als Float in Pfund | Type Hints, Schemas, ein Money-Typ |
| Bedeutung | Statisch | status == 4 bedeutet „Fahrer zugewiesen“ | Benannte Konstanten oder eine Aufzählung, über eine einzige Definition geteilt |
| Position | Statisch | quote(2.5, 51.5, -0.12, True) | Schlüsselwortargumente, ein Parameterobjekt, benannte JSON-Felder |
| Algorithmus | Statisch | App und Server berechnen dieselbe Warenkorb-Prüfsumme | Eine gemeinsame Bibliothek, oder eine Seite berechnet das Ergebnis und sendet es |
| Ausführung | Dynamisch | Die Zahlung muss autorisiert sein, bevor das Restaurant benachrichtigt wird | Die Abfolge an einer Stelle kapseln (ein Workflow oder eine Saga) |
| Timing | Dynamisch | Die Fahrer-App gibt nach 5 s auf, die Disposition braucht bis zu 8 s | Die Interaktion asynchron machen; Timeouts aus SLOs ableiten |
| Wert | Dynamisch | Frontend und Backend halten jeweils die Liste der Liefergebiete | Ein Eigentümer der Daten; andere fragen sie ab oder abonnieren sie |
| Identität | Dynamisch | Zwei Module müssen in derselben Datenbanktransaktion schreiben | Einem Modul die Zuständigkeit für die Unit of Work geben |
Stärke, Lokalität und Grad
Jedes Auftreten von Connascence lässt sich anhand von drei Eigenschaften beurteilen. Die Stärke beschreibt, wie schwer die Form zu entdecken und zu ändern ist: Name ist schwach, weil Werkzeuge ihn finden und umbenennen; Bedeutung ist stärker, weil nichts die magischen Werte kennzeichnet; Timing und Identität sind am stärksten, weil sie sich womöglich erst unter Last oder in der Produktion zeigen. Die Reihenfolge in der Tabelle ist die übliche Rangfolge, auch wenn die Autoren bei den statischen Formen leicht voneinander abweichen (manche ordnen Position unter Bedeutung ein).
Die Lokalität beschreibt, wie nah die connascenten Elemente beieinander liegen. Positionsparameter zwischen zwei privaten Hilfsfunktionen in derselben Datei sind harmlos: Wer die eine ändert, sieht die andere. Positionsfelder in einer Nachricht zwischen Services verschiedener Teams sind gefährlich, weil die Menschen, die gemeinsam ändern müssen, nicht zusammensitzen, nicht gemeinsam releasen und womöglich nicht einmal voneinander wissen.
Der Grad beschreibt, wie viele Elemente beteiligt sind. Eine magische Zahl, die zwei Funktionen teilen, ist ein Ärgernis; dieselbe Zahl in vierzig Dateien in sechs Services ist ein Migrationsprojekt. Der Grad lässt sich zählen: Kommt der Statuscode 3 an 14 Stellen im Lagerservice, an 9 im Benachrichtigungsservice und an 5 in den Views der Reporting-Datenbank vor, beträgt der Grad 28, und seine Bedeutung zu ändern heißt, 28 Änderungen über drei Teams und mindestens zwei Deployments hinweg zu koordinieren, mit einer Datenmigration für die Views.
Die Stärke muss mit wachsender Entfernung sinken
Die Leitlinien
Page-Jones’ Rat lässt sich in drei Aussagen zusammenfassen: Minimieren Sie die Connascence insgesamt, indem Sie ein System in gekapselte Elemente zerlegen; minimieren Sie die Connascence, die Kapselungsgrenzen überschreitet; und maximieren Sie die Connascence innerhalb dieser Grenzen. Die letzte überrascht viele, ist aber einfach Kohäsion in anderen Worten: Was sich gemeinsam ändern muss, sollte zusammen liegen.
Jim Weirich, der Ruby-Entwickler, der vor allem als Autor des Build-Werkzeugs Rake bekannt ist, belebte die Idee ab 2009 in Vorträgen für eine neue Generation wieder, darunter „The Building Blocks of Modularity“ (2009 auf mehreren Ruby-Konferenzen gehalten, unter ihnen die MountainWest RubyConf) (den er scherzhaft eine große vereinheitlichte Theorie der Softwareentwicklung nannte) und „Connascence Examined“. Er verdichtete die Praxis zu zwei Regeln. Die Regel der Lokalität: Je weiter zwei Elemente voneinander entfernt sind, desto schwächer sollte die Connascence zwischen ihnen sein. Die Regel des Grades: Wandeln Sie starke Formen der Connascence in schwächere um, besonders wenn viele Elemente beteiligt sind.
In der Praxis ergeben sich daraus drei Schritte, grob nach Vorrang geordnet:
Die Form abschwächen. Ersetzen Sie Bedeutung durch Name (eine benannte Konstante), Position durch Name (Schlüsselwortargumente, benannte Felder), Algorithmus durch Name (eine gemeinsame Funktion, die beide Seiten aufrufen), Ausführung durch Kapselung (eine Methode, die die Schritte in der richtigen Reihenfolge ausführt).
Die Lokalität erhöhen. Müssen zwei Elemente eine starke Form teilen, rücken Sie sie näher zusammen: in dieselbe Klasse, dasselbe Modul, dieselbe Komponente oder denselben Service, verantwortet vom selben Team.
Den Grad verringern. Teilen viele Elemente eine Konvention, leiten Sie sie über eine einzige Definition, einen einzigen Eigentümer oder einen einzigen Adapter, sodass nur wenige Stellen das Detail kennen.
Ausgearbeitetes Beispiel
Ausgearbeitetes Beispiel: Positionsparameter und magische Werte ersetzen
Eine Fahrdienst-App hat eine Funktion, die von der Buchungs-API, dem Scheduler und einem Admin-Werkzeug genutzt wird. Ihre Signatur ist über zwei Jahre gewachsen: book(rider_id, 51.501, -0.142, 51.515, -0.072, 2, True, 0). Lesen Sie die Connascence ab und refaktorieren Sie die Funktion.
| Position | Acht Positionsargumente. Werden Abhol- und Zielkoordinaten vertauscht, besteht der Code trotzdem die Typprüfung und schickt den Fahrer stillschweigend an den falschen Ort. |
|---|---|
| Bedeutung | 2 ist die Fahrzeugklasse (1 Standard, 2 groß, 3 barrierefrei); True bedeutet „mit Karte zahlen“; 0 bedeutet „sofort buchen“, während jede andere Zahl eine geplante Zeit in Epochensekunden ist. |
| Grad | Eine Suche findet 31 Aufrufstellen in drei Komponenten, sodass jeder neue Parameter 31 Änderungen an einer festen Position bedeutet. |
| Schritt 1: Name statt Position | Führen Sie einen Typ Location und reine Schlüsselwortargumente ein, sodass Aufrufer pickup=Location(lat=51.501, lon=-0.142) schreiben. |
| Schritt 2: Name statt Bedeutung | Ersetzen Sie 2 durch VehicleClass.LARGE, True durch Payment.CARD und 0 durch when=None mit der Bedeutung „sofort“. |
| Schritt 3: Grad verringern | Fassen Sie die Argumente in einem Objekt BookingRequest zusammen; ein später hinzugefügtes optionales Feld berührt nur den Code, der es braucht. |
| Ergebnis | Connascence der Position und der Bedeutung (stark, Grad 31) wird zu Connascence des Namens und des Typs (schwach), die Typprüfer und IDE verifizieren und automatisch umbenennen können. |
Am Verhalten hat sich nichts geändert; das Refactoring hat nur geändert, welche Absprachen Aufrufer einhalten müssen und wie sichtbar diese Absprachen sind.
Nehmen Sie die Änderung in Schritten vor, die alte Aufrufer funktionsfähig halten, etwa indem Sie ein Release lang beide Formen akzeptieren und die Verwendung der alten protokollieren.
from dataclasses import dataclass
from datetime import datetime
from enum import Enum
class VehicleClass(Enum):
STANDARD = "standard"
LARGE = "large"
ACCESSIBLE = "accessible"
class Payment(Enum):
CARD = "card"
CASH = "cash"
@dataclass(frozen=True, kw_only=True)
class Location:
lat: float
lon: float
@dataclass(frozen=True, kw_only=True)
class BookingRequest:
rider_id: str
pickup: Location
dropoff: Location
vehicle: VehicleClass = VehicleClass.STANDARD
payment: Payment = Payment.CARD
when: datetime | None = None # None means now
def book(request: BookingRequest) -> str: ...Connascence über Service-Grenzen hinweg
Mark Richards und Neal Ford stellen Connascence in Fundamentals of Software Architecture (2020; zweite Auflage 2025) neben Kohäsion und Kopplung als eines der zentralen Maße für Modularität vor und argumentieren, dass sie zwischen Services ebenso nützlich ist wie im Code. Liest man die Formen mit einem verteilten System im Kopf, entspricht jede einem vertrauten Problem:
Name und Typ über Services hinweg sind die Absprachen, die ein veröffentlichtes Schema explizit macht: Feldnamen und -typen in einem OpenAPI-Dokument, einem Avro- oder Protobuf-Schema oder einem Event-Katalog. Diese Formen wollen Sie, und Contract-Tests können sie prüfen.
Bedeutung über Services hinweg ist der gemeinsame Statuscode oder das unerklärte Flag: was Abschnitt 3.2 semantische Kopplung nannte. Bevorzugen Sie selbstbeschreibende Werte ("status": "rider_assigned") gegenüber Zahlen und Einheiten in Feldnamen (fee_pence, timeout_ms) gegenüber Annahmen. Einheiten verdienen besondere Sorgfalt: Der Mars Climate Orbiter der NASA ging 1999 verloren, weil die Bodensoftware eines Teams Impulswerte in Pound-Force-Sekunden lieferte, während die Navigationssoftware, die sie verarbeitete, Newtonsekunden erwartete, eine Connascence der Bedeutung zwischen Organisationen, die niemand explizit gemacht hatte.
Position über Services hinweg zeigt sich beim Austausch von Dateien mit fester Feldbreite oder CSV-Dateien und bei positionsbasierten Nachrichtenformaten; benannte Felder beseitigen sie. Algorithmus zeigt sich, wenn zwei Services unabhängig voneinander denselben Preis, Rabatt oder Hash berechnen müssen; die Abhilfe besteht meist darin, dass ein Service ihn berechnet und das Ergebnis sendet.
Ausführung und Timing über Services hinweg sind die harten Probleme verteilter Systeme, und Timing ist die Connascence hinter der zeitlichen Kopplung aus Abschnitt 3.2: ein Consumer, der annimmt, dass der Datenbank-Schreibvorgang des Producers sichtbar ist, bevor das Event eintrifft; eine Kette synchroner Aufrufe, deren Timeouts nicht korrekt verschachtelt sind; ein Workflow, der nur funktioniert, wenn Nachrichten in der richtigen Reihenfolge eintreffen. Interaktionen asynchron, idempotent und reihenfolgetolerant zu machen, schwächt diese Formen ab; Muster wie Sagas und die Outbox (Kapitel 6) gibt es vor allem, um sie zu beherrschen.
Wert und Identität über Services hinweg sind Anzeichen für eine Grenze an der falschen Stelle. Müssen zwei Services einen Wert konsistent halten (die Bestellsumme im Bestellservice und die Rechnungssumme in der Abrechnung) oder dieselbe Zeile in derselben Transaktion bearbeiten, dann sollte entweder ein Service diese Daten besitzen und der andere sie anfragen, oder die beiden Services sollten wahrscheinlich einer sein. Starke Connascence über ein Netzwerk hinweg ist geradezu die Definition eines verteilten Monolithen.
Prüfen Sie Ihr Verständnis
Eine Funktion erwartet (width, height), und ein Aufrufer übergibt (height, width). Welche Form der Connascence wurde verletzt, und wie lässt sie sich am einfachsten abschwächen?
Connascence der Position. Verwenden Sie Schlüsselwortargumente oder ein Parameterobjekt, damit die Absprache zu einer des Namens wird.
Warum ist Connascence der Bedeutung stärker als Connascence des Namens?
Werkzeuge und Lesende können jede Verwendung eines Namens finden, aber nichts verbindet die einzelnen Verwendungen eines magischen Werts wie 3, sodass Änderungen leicht übersehen werden.
Zwei Services müssen das Kreditlimit eines Kunden immer in derselben Transaktion aktualisieren. Was deutet das an?
Starke Connascence der Identität oder des Werts über eine Netzwerkgrenze hinweg: Die Daten brauchen wahrscheinlich einen einzigen Eigentümer, oder die beiden Services gehören zusammen.
Warum kann starke Connascence innerhalb einer einzelnen kleinen Funktion völlig akzeptabel sein?
Weil die Lokalität hoch ist: Wer ein Element ändert, sieht das andere sofort, sodass Kosten und Risiko, sie konsistent zu halten, winzig sind.
Quellen und weiterführende Literatur
Haben Sie eine Frage zu diesem Abschnitt? ArchitectBot, der KI-Lernassistent des Kurses, antwortet zuerst aus dem Kurs.
Fragen: „Unser Bestell- und unser Rechnungsservice berechnen beide die Bestellsumme und weichen manchmal um einen Penny voneinander ab. Wie würde ich diese Kopplung im Sinne der Connascence beschreiben, und was sollten wir ändern?“