Was sind die Vorteile der Verwendung von Dependency Injection- und IoC-Containern?


62

Ich habe vor, einen Vortrag über Abhängigkeitsinjektion und IoC-Container zu halten, und ich suche nach guten Argumenten für die Verwendung.

Was sind die wichtigsten Vorteile dieser Technik und dieser Tools?


1
Siehe hier und hier für Stackoverflow Antworten und hier für einen guten ganzen Artikel auf IoC. Und wenn Sie zum Vergleich Argumente dagegen haben wollen, gehen Sie hier auf SO.
Jesse C. Slicer

14
Nicht um ein Hintern zu sein ... aber wenn Sie nicht wissen, warum DI / IOC verwendet werden sollte, warum reden Sie dann darüber? eine Wette verlieren? ;-)
Steven A. Lowe

2
@Steven, sein Chef hätte ihn vielleicht darum gebeten.

1
@Steven, ich benutze DI schon die ganze Zeit (manche würden zu oft sagen :-D), ich suche nur nach ein paar guten Argumenten, um andere Leute dazu zu bringen, es zu benutzen.
Andy Lowry

2
Über die Übernutzung von DI wird selten gesprochen . Wenn Sie jede einzelne Entscheidung verzögern, erstellen Sie das OO-Äquivalent des Spaghetti-Codes. Ein kohärentes Design setzt voraus, dass irgendwann eine echte Entscheidung getroffen wird.
Macneil

Antworten:


47

Für mich ist es am wichtigsten, die Einhaltung des Grundsatzes der einheitlichen Verantwortung zu vereinfachen .

DI / IoC erleichtert mir das Verwalten von Abhängigkeiten zwischen Objekten. Dies erleichtert es mir wiederum, zusammenhängende Funktionen in einen eigenen Vertrag (Schnittstelle) aufzuteilen. Infolgedessen wurde mein Code wesentlich modularer, seit ich von DI / IoC erfahren habe.

Ein weiteres Ergebnis davon ist, dass ich meinen Weg zu einem Entwurf, der das Open-Closed-Prinzip unterstützt, viel leichter durchschaue . Dies ist eine der vertrauensinspirierendsten Techniken (nach automatisierten Tests). Ich bezweifle, dass ich die Tugenden des Open-Closed-Prinzips genug vertreten kann.

DI / IoC ist eines der wenigen Dinge in meiner Programmierkarriere, die sich als "Game Changer" erwiesen haben. Es gibt eine große Qualitätslücke zwischen Code, den ich vor und nach dem Erlernen von DI / IoC geschrieben habe. Lassen Sie mich das noch etwas hervorheben. Enorme Verbesserung der Codequalität.


3
Warum ist das Open-Closed-Prinzip so wichtig? Wenn Sie das Gefühl haben, eine API / Schnittstelle ändern zu müssen, warum sollten Sie das nicht tun?
Arne Evertsson

@ArneEvertsson Hören Sie, wie Robert C. Martin über das Open-Closed-Prinzip spricht. Du wirst erleuchtet sein.
Alternatex

@AmeEvertsson Open-Closed ist sehr wichtig, wenn Ihr Code (z. B. als kommerzielles Produkt) als Modul zur Verwendung durch andere bereitgestellt wird, da Ihr Code dadurch anpassungsfähiger wird, ohne dass Sie ihn ändern müssen
James Ellis-Jones

2
DI vereinfacht das Verwalten von Abhängigkeiten nicht, da es erheblich komplexer ist als das einfache Erstellen einer Abhängigkeit zu einer konkreten Klasse. Es bietet zwar Flexibilität, aber diese Flexibilität wird häufig nicht benötigt, es sei denn, Sie führen "ordnungsgemäße" Komponententests durch. Beide beschriebenen Hauptvorteile gelten auch für den Service Locator, der einfacher ist.
James Ellis-Jones

1
Ich habe diese Antwort vor Jahren abgelehnt. Hier einige Anmerkungen: 1) In der Praxis funktioniert die umfassende Verwendung von DI in der Regel gegen SRP, da Programmierer ihren injizierten "Controllern", "Diensten", "DAOs" usw. immer wieder Methoden hinzufügen, anstatt neue Klassen für zu erstellen neue Funktionalität. Normalerweise geschieht dies in Java- und C # .NET-Projekten, die ein DI-Framework oder einen DI-Container verwenden. 2) Das Open-Closed-Prinzip war nur eine Illusion von Bertrand Meyer über den Nutzen der Klassenvererbung (Implementierung). Wenn Sie es in seinem über 1400 Seiten umfassenden Buch suchen, werden Sie sehen, was ich meine - es ist wirklich albern.
Rogério

9

Die Beispiele, die mir wirklich die Augen geöffnet haben, haben gezeigt, wie es möglich war, die auf diese Weise erstellten Objekte auf einfache Weise zu testen. Zuvor hatte ich Probleme, Objekte für einen Komponententest zu isolieren. Ich habe oft Tests geschrieben, um mit einem viel größeren System zu interagieren. Dies war sehr schwierig, da das gesamte System viel weniger vorhersehbar und anfälliger für Änderungen als die einzelnen Komponenten war.


3

Vorteile von Abhängigkeitsinjektionen sind:

  1. Ihr Code ist sauber und besser lesbar.
  2. Codes sind lose gekoppelt.
  3. Je mehr die Implementierungen in der XML-Datei konfiguriert sind, desto wiederverwendbarer können sie in einem anderen Kontext verwendet werden.
  4. Code kann leicht mit verschiedenen Mock-Implementierungen getestet werden.

1

Ich denke, der tatsächliche Nutzen ist eher politischer als technischer Natur. DI ist einfach eine Alternative zum Service Locator- Muster, sonst nichts. Es macht es nicht einfacher, Prinzipien wie SRP oder OCP zu folgen oder Schichten zu entkoppeln. Andere Befragte hier verwirren unterschiedliche Konzepte und Techniken, IMO.

Sie können dieselben Ziele in Bezug auf hohe Kohäsion und niedrige Kopplung erreichen, indem Sie Service Locators verwenden oder indem Sie Abhängigkeiten direkt instanziieren, wann immer dies möglich ist (was die meiste Zeit der Fall ist).

Ich weiß, dass viele dieser Meinung nicht zustimmen werden. Ich werde gerne konkrete Beispiele diskutieren.


2
Das direkte Aufrufen eines Service-Locators oder das Instanziieren einer konkreten Abhängigkeit führt jedoch in der Regel dazu, dass Ihre Abhängigkeiten fest verdrahtet sind oder zumindest, woher Ihre Abhängigkeiten stammen. Das scheint den Zweck von DI zu vereiteln. Sie müssen auch noch den Service Locator injizieren.
Matt H

Die Verwendung eines Service Locator verkabelt nichts außer der Verwendung der Service Locator-Klasse selbst, die normalerweise nicht "injiziert" wird. Das Instanziieren einer konkreten Implementierungsklasse ist in Fällen, in denen keine externe Konfiguration erforderlich ist, in Ordnung (z. B. instanziieren Programmierer die ArrayList-Klasse normalerweise direkt, anstatt DI zu verwenden - was zu viel wäre).
Rogério

1
Sie erwähnen "niedrige Kopplung" und später sagen Sie, dass ein Service Locator keinen Einfluss auf den Kopplungsgrad einer Anwendung hat. Genauso wie ich Kollaborateure direkt im Code instanziiere, kann ich mir keinen perfekteren Weg vorstellen, um ein Objekt mit seinen Abhängigkeiten zu koppeln. Wie testen Sie beide Szenarien? Ich bin mit allem, was Sie gesagt haben, völlig anderer Meinung.
Clint Eastwood

@ Jonathan Sie sollten den Artikel lesen, der DI dann vorstellte ; Der Autor schließt mit der Aussage, dass DI und ServiceLocator "ungefähr gleichwertig" sind, mit einem "leichten Rand" für letztere. Die entscheidende Kopplung besteht zwischen einer Komponente und anderen Komponenten, die mehrere Implementierungen haben können. Ein ServiceLocator ist ein Infrastrukturservice mit nur einer Implementierung. Hinweis: Ich habe geschrieben: "Abhängigkeiten instanziieren, wann immer anwendbar ". natürlich, wenn Sie benötigen Konfiguration aus der Benutzung zu trennen, würden Sie tun es nicht.
Rogério

1
@Jonathan In Bezug auf Unit-Tests ist es ein Mythos, dass das Instanziieren von Kollaborateuren die Erstellung solcher Tests verhindert. Es gibt bekannte Spott-Tools, mit denen eine Klasse von Abhängigkeitsimplementierungen isoliert werden kann, unabhängig davon, ob sie injiziert werden oder nicht.
Rogério

-1

Wenn DI verwendet wird, um innere Objekte für Testzwecke freizulegen, wurde das Muster missbraucht.


1
Was meinst du mit "inneren Objekten"? In der realen OOP (beachten Sie, dass wahrscheinlich nur 1% der Programmierer wissen, was das wirklich bedeutet), gibt es Objekte, die über das Senden von Nachrichten (dh Methodenaufrufe) miteinander kommunizieren. In diesem Sinne muss jedes Objekt eine einzelne Verantwortung haben, es gibt keine "wichtigeren" Objekte als die anderen ... jedes einzelne hat eine einzelne Aufgabe und sie arbeiten zusammen, um die vom gesamten System bereitgestellte Funktionalität zu erreichen. Es ist wichtig, jedes Objekt isoliert zu testen, damit wir wissen, dass wir keinen Fall verpasst haben. Das ist, was DI wirklich gut kann.
Clint Eastwood

Ich habe vergessen.
thomas-peter
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.