Fachbegriff für das Gegenteil von Abhängigkeitsinjektion?

12

Dies ist eher eine Nomenklatur (technisches Schreiben) als eine rein technische Frage. Ich versuche, ein Refactoring-Angebot zu schreiben (und es mir selbst zuweisen zu lassen), in dessen Mittelpunkt die Erweiterung der Abhängigkeitsinjektion in unserer Anwendung steht. Während wir Spring für das automatische Verdrahten von Bohnen verwenden, gibt es immer noch Instanzen, die die Verwendung von Bohnen instantiieren MyClass obj = new MyClass(...)und die vollständig injiziert werden könnten. Ich möchte meinen Vorschlag mit einer eleganten Nomenklatur versehen und mit einem richtigen Begriff auf das gegenüberliegende Entwurfsmuster von DI verweisen.

Ist "enge Kopplung" ein adäquater Begriff, der als Antonyme auf DI steht?

amphibient
quelle
1
Ja, Coupling beschreibt sowohl die Verwendung expliziter Klassennamen in anderen Klassen als auch den resultierenden Status einer Codebasis.
Kilian Foth
11
Nein, enge Kopplung beschreibt nur die Eigenschaft des resultierenden Codes, nicht das Gegenteil von DI. Sie können DI verwenden und haben aus ganz anderen Gründen immer noch eine enge Kopplung.
Doc Brown
1
Einverstanden, dass DI und enge Kopplung keine Gegensätze sind .
Eric King
@EricKing vorführen. +1 übrigens.
candied_orange
1
"Abhängigkeitsabsaugung" .
SeldomNeedy

Antworten:

30

Enge Kopplung ist viel mehr als das, womit Abhängigkeitsinjektion zu tun hat.

Die Abhängigkeitsinjektion externalisiert eine Entscheidung über die Implementierung. Dies ist ein langer Weg zur Entkopplung, aber die Kopplung ist mehr als nur das.

Ein gutes Antonyme für die Abhängigkeitsinjektion ist die harte Codierung einer Abhängigkeit . Wenn Sie ein Verhaltensobjekt konstruieren (neue verwenden oder eine Factory direkt verwenden), haben Sie zwei verschiedene Aspekte zusammengeführt. Ein Service-Locator hilft beim Entkoppeln, lässt Sie jedoch mit dem Service-Locator selbst verbunden.

Kupplung ist mehr als nur eine Trennung von Konstruktion und Verhalten. Wenn ich 101 Methoden habe, die in einer bestimmten Reihenfolge von Klasse A bis Klasse B aufgerufen werden müssen, bin ich eng miteinander verbunden. Es spielt keine Rolle, wie wunderbar Konstruktion und Verhalten voneinander getrennt sind.

Die Kopplung ist ein Maß für die gegenseitige Abhängigkeit der beiden Objekte. Alles, was dazu beiträgt, Änderungen an einem zu erschweren, ohne den anderen zu beeinträchtigen, trägt zur Kopplung bei. Die Abhängigkeitsinjektion hilft dabei, aber das ist noch nicht alles.

kandierte_orange
quelle
Ja, hartes Codieren (eine Abhängigkeit) im Gegensatz zum Injizieren (zur Laufzeit) ist genau das, was ich auch vorschlagen wollte, Sie waren nur ein bisschen schneller als ich.
Doc Brown
7
@ DocBrown Ich wünschte manchmal, dieser Ort hätte nicht so viel Wert darauf gelegt, schnell zu sein. Ich würde gerne hören, wie Sie es ausdrücken würden.
candied_orange
Gute Antwort - Abhängigkeitsinjektion bedeutet keine Entkopplung. Der Glaube an etwas anderes führt zu einer schlechten Straße
Ant P
1
@CandiedOrange Vielleicht sollte jemand in Meta vorschlagen, dass Antworten für einen bestimmten Zeitraum verborgen bleiben. Und / oder dass Stimmen Nstundenlang für die Öffentlichkeit verborgen bleiben ... oder bis eine Antwort ausgewählt wird. Ich weiß, dass ich nicht ganz objektiv bin, wenn eine Antwort bereits 10 Stimmen hat und die anderen 5 Antworten keine haben!
Svidgen
1
@svidgen suche "schnellste pistole im westen" auf meta. Das Problem hat bereits eine lange Geschichte.
candied_orange
6

Genau genommen ist die Abhängigkeitsinjektion nur wirklich gegen die NICHT- Abhängigkeitsinjektion und daher gegen jede Abhängigkeitsverwaltungsstrategie, die keine Abhängigkeitsinjektion ist.

[Unerwünschte] Kopplung ist zwar kein genaues orthogonales Problem, kann jedoch in beiden Fällen auftreten oder verringert werden. Diese sind beide gekoppelt an DependencyClass:

public DependencyInjectedConstructor(DependencyClass dep) {
  dep.do();
}

public DependencyLookupConstructor() {
  var dep = new DependencyClass();
  dep.do();
}

DependencyLookupConstructorist DependencyClassin diesem Fall an ein bestimmtes gekoppelt . Aber sie sind beide verbunden mit DependencyClass. Das wahre Übel, wenn es eines hier gibt, ist nicht unbedingt die Kopplung, es DependencyLookupConstructormuss sich ändern, wenn DependencyClassplötzlich seine eigenen Abhängigkeiten injiziert werden müssen 1 .

Jedoch wird dieser Konstruktor / Klasse noch mehr lose gekoppelten:

public DependencyLocatingConstructor() {
  var dep = ServiceLocator.GetMyDoer();
  dep.do();
}

Wenn Sie in C # arbeiten, wird die oben Ihre erlauben ServiceLocatorzurückzukehren etwas , wenn GetMyDoer()aufgerufen wird, solange es hat können , do()was DependencyLocatingConstructores hat do(). Sie erhalten den Vorteil der Signaturvalidierung zur Kompilierungszeit, ohne an eine vollständige Schnittstelle 2 gekoppelt zu sein .

Also, nimm dein Gift.

Aber im Grunde, wenn es ein konkretes „Gegenteil“ von Dependency Injection, wäre es etwas anderes im Bereich der seine „Dependency - Management - Strategien.“ Wenn Sie im Gespräch eine der folgenden Methoden verwenden, wird dies unter anderem als NICHT- Abhängigkeitsinjektion erkannt :

  • Service Locator Pattern
  • Abhängigkeitsfinder / Speicherort
  • Direkte Objekt- / Abhängigkeitskonstruktion
  • Versteckte Abhängigkeit
  • "Nicht-Abhängigkeitsinjektion"

1. Ironischerweise sind einige der Probleme, die DI auf höheren Ebenen löst, eine Folge der [Über-] Verwendung von DI auf niedrigeren Ebenen. Ich habe die Freude an der Arbeit auf Codebases mit unnötiger Komplexität hatte überall als Folge der Unterbringung der Handvoll von Orten , an denen die Komplexität tatsächlich geholfen ... Ich bin zwar durch schlechte Belichtung vorgespannt ist .

2. Die Verwendung des Service-Standorts ermöglicht es Ihnen auch, verschiedene Abhängigkeiten desselben Typs durch ihre funktionale Rolle im aufrufenden Code zu spezifizieren , während Sie weitgehend unabhängig davon sind, wie die Abhängigkeit aufgebaut ist. Angenommen, Sie müssen Useroder IUserfür verschiedene Zwecke lösen : ZB Locator.GetAdministrator()versus Locator.GetAuthor()- oder was auch immer. Mein Code kann nach den funktionalen Anforderungen fragen, ohne zu wissen, welche Schnittstellen er unterstützt.

Svidgen
quelle
2
Die Rettung für DependencyInjectedConstructor(DependencyClass dep)ist, dass DependencyClass eine Schnittstelle oder eine abstrakte Klasse sein könnte. Aus diesem Grund macht es mich traurig, dass C # -Codierer wie in ein Schnittstellenpräfix verwenden IDependency. Als Kunde ist es nicht meine Sache, was diese Abhängigkeitssache ist. Solange ich es nicht baue, muss ich nur wissen, wie ich damit reden soll. Was es ist, ist das Problem eines anderen.
candied_orange
Punkte sein, DI noch Paaren Sie zu dieser Schnittstelle, und es nicht erforderlich , dass DependencyClassüberhaupt eine abstrakte Schnittstelle sein. Es ist nur erforderlich, dass die Konstruktions- / Konfigurations- / Standortlogik "woanders" vorhanden ist. ... Nun, und was die Frage
betrifft
Eigentlich ... Ich bin vielleicht ein bisschen verrückt, wenn ich sage, DI koppelt Sie notwendigerweise an eine Schnittstelle, sogar in C #. Obwohl ich sie in C # vermieden habe, habe ich den Eindruck, ich könnte auch dynamicParameter akzeptieren . (Aber nicht varParameter, wenn der Speicher dient.) Also, mit DI in C #, ich glaube , ich entweder Code gegen eine Schnittstelle haben, oder ich muss völlig forgo die Kompilierung-Validierung.
Svidgen
Objekte sind an die Schnittstellen gekoppelt. Ob Sie das Schlüsselwort interface verwenden oder nicht. Das ist, was eine richtige Schnittstelle ist. Alles, woran Sie gekoppelt sein MÜSSEN. Was Sie verdrängen, sind Implementierungsdetails und zusätzliche Dinge, die Sie nicht benötigen. Wir können dies formalisieren, indem wir das Schlüsselwort interface verwenden, damit der Client der Welt mitteilt: "Alles, was ich brauche, ist dies". Das müssen wir aber nicht. Mist, wir können Enten tippen, auch in einigen Sprachen.
candied_orange
Ich bin mir nicht sicher, ob wir uns überhaupt nicht einig sind. Aber zur Verdeutlichung ... Objekte sind intern an ihre eigenen Schnittstellen gekoppelt , ja. Die Schnittstelle selbst erzwingt jedoch nur dann eine Abhängigkeitskopplung, wenn die Schnittstelle explizit benannt wird. In C # können Sie mit dynamicoder varund dem Abrufen eines Objekts von einem Locator die Schnittstelle ignorieren und eine beliebige Klasse verwenden, die do()Ihren Anforderungen entspricht, unabhängig davon, ob diese Klasse eine IDoerSchnittstelle implementiert . Mit anderen Worten, wenn wir A-> B <-C haben, entkoppelt DI A von C, erfordert jedoch, dass sowohl A als auch C an B gekoppelt sind, und verhindert die Verwendung von D, selbst wenn D dies will do().
Svidgen
2

Ich weiß nicht , dass es bestimmte, allgemein anerkannte Industrie Terminologie, aber Alternativen , die den Sinn kommen , sind interne Instanzerstellung , interne Abhängigkeiten Erstellung , lokale Abhängigkeiten oder lokal scoped Abhängigkeiten .

mcknz
quelle
2
Ich mag, instance creationaber es ist nicht spezifisch genug. DI erstellt Instanzen, jedoch über den Controller und nicht auf Anwendungsebene. Vielleichtinternal instance creation
amphibient
1

Ich würde mit Abhängigkeitsverkapselung gehen . Dies drückt aus, dass die Abhängigkeit gesperrt ist, anstatt zu besuchen und wieder zu verlassen.

Martin Maat
quelle