Nach dem von Martin Fowler verfassten Artikel ist die Umkehrung der Steuerung das Prinzip, bei dem der Steuerungsfluss eines Programms invertiert wird: Anstelle des Programmierers, der den Ablauf eines Programms steuert, übernehmen die externen Quellen (Framework, Dienste, andere Komponenten) die Kontrolle es. Es ist, als würden wir etwas an etwas anderes anschließen. Er erwähnte ein Beispiel zu EJB 2.0:
Beispielsweise definiert die Session Bean-Schnittstelle ejbRemove, ejbPassivate (im Sekundärspeicher gespeichert) und ejbActivate (aus dem passiven Zustand wiederhergestellt). Sie können nicht steuern, wann diese Methoden aufgerufen werden, sondern nur, was sie tun. Der Container ruft uns an, wir nennen es nicht.
Dies führt zu dem Unterschied zwischen Framework und Bibliothek:
Die Inversion der Kontrolle ist ein wesentlicher Bestandteil dessen, was ein Framework von einer Bibliothek unterscheidet. Eine Bibliothek besteht im Wesentlichen aus einer Reihe von Funktionen, die Sie aufrufen können. Diese sind heutzutage normalerweise in Klassen unterteilt. Jeder Aufruf erledigt einige Arbeiten und gibt die Kontrolle an den Client zurück.
Ich denke, der Standpunkt, dass DI IOC ist, bedeutet, dass die Abhängigkeit eines Objekts invertiert ist: Anstatt seine eigenen Abhängigkeiten, seinen Lebenszyklus zu steuern, erledigt es etwas anderes für Sie. Aber, wie Sie mir von Hand über DI erzählt haben, ist DI nicht unbedingt IOC. Wir können immer noch DI und kein IOC haben.
In diesem Artikel (aus der Pococapsule, einem anderen IOC-Framework für C / C ++) wird jedoch vorgeschlagen, dass die IOC-Container und DI-Frameworks aufgrund von IOC und DI J2EE weit überlegen sind, da J2EE den Framework-Code in die Komponenten mischt Dadurch wird es nicht zu einem einfachen alten Java / C ++ - Objekt (POJO / POCO).
Inversion anderer Kontrollcontainer als des Abhängigkeitsinjektionsmusters (Archivlink)
Zusätzliche Lektüre, um zu verstehen, was das Problem mit dem alten komponentenbasierten Entwicklungsframework ist, das zum zweiten Artikel oben führt: Warum und was von Inversion of Control (Archivlink)
Meine Frage : Was genau ist IOC und DI? Ich bin verwirrt. Basierend auf Pococapsule ist IOC etwas Wichtigeres als nur die Umkehrung der Steuerung zwischen Objekten oder Programmierern und Frameworks.
Antworten:
IoC ist ein allgemeiner Begriff, der bedeutet, dass die Anwendung die Methoden nicht in einem Framework aufruft, sondern dass das Framework Implementierungen aufruft, die von der Anwendung bereitgestellt werden.
DI ist eine Form von IoC, bei der Implementierungen über Konstruktoren / Setter / Service-Lookups an ein Objekt übergeben werden, von denen das Objekt abhängig ist, um sich korrekt zu verhalten.
IoC ohne DI wäre beispielsweise das Vorlagenmuster, da die Implementierung nur durch Unterklassifizierung geändert werden kann.
DI-Frameworks verwenden DI und können Schnittstellen (oder Anmerkungen in Java) definieren, um die Übergabe der Implementierungen zu vereinfachen.
IoC-Container sind DI-Frameworks, die außerhalb der Programmiersprache arbeiten können. In einigen Fällen können Sie konfigurieren, welche Implementierungen in weniger invasiven Metadatendateien (z. B. XML) verwendet werden sollen. Mit einigen können Sie IoC ausführen, was normalerweise unmöglich wäre, wie das Einfügen einer Implementierung bei Pointcuts .
Siehe auch diesen Artikel von Martin Fowler .
quelle
Kurz gesagt, IoC ist ein viel weiter gefasster Begriff, der DI umfasst, aber nicht darauf beschränkt ist
Der Begriff Inversion of Control (IoC) bezeichnete ursprünglich jede Art von Programmierstil, bei dem ein Gesamtrahmen oder eine Laufzeit den Programmfluss kontrollierte
Bevor DI einen Namen hatte, begannen die Leute, Frameworks, die Abhängigkeiten verwalten, als Inversion von Kontrollcontainern zu bezeichnen, und bald driftete die Bedeutung von IoC allmählich in Richtung dieser bestimmten Bedeutung: Inversion der Kontrolle über Abhängigkeiten.
Inversion of Control (IoC) bedeutet, dass Objekte keine anderen Objekte erstellen, auf die sie sich verlassen, um ihre Arbeit zu erledigen. Stattdessen erhalten sie die benötigten Objekte von einer externen Quelle (z. B. einer XML-Konfigurationsdatei).
Dependency Injection (DI) bedeutet, dass dies ohne Objektintervention erfolgt, normalerweise durch eine Framework-Komponente, die Konstruktorparameter übergibt und Eigenschaften festlegt.
quelle
Quelle
IoC ( I nversion o f C teuerung): - Es ist ein allgemeiner Begriff und auf verschiedene Weise implementiert (Veranstaltungen, Teilnehmer usw.).
DI ( D ependency I njection): - DI ist ein Untertyp von IoC und wird durch Konstruktorinjektion, Setterinjektion oder Schnittstelleninjektion implementiert .
Spring unterstützt jedoch nur die folgenden zwei Typen:
NullPointerException: bean does not exist
. Die Konstruktorinjektion ist eine bewährte Methode zum Injizieren von Abhängigkeiten.quelle
DI ist eine Teilmenge von IoC
Hier sind einige andere Techniken, um IoC zu erreichen .
quelle
Da sich alle Antworten auf die Theorie konzentrieren, möchte ich anhand eines ersten Beispielansatzes demonstrieren:
Angenommen, wir erstellen eine Anwendung, die eine Funktion zum Senden von SMS-Bestätigungsnachrichten enthält, sobald die Bestellung versandt wurde. Wir werden zwei Klassen haben, eine ist für das Senden der SMS (SMSService) und eine andere für die Erfassung von Benutzereingaben (UIHandler) verantwortlich. Unser Code sieht wie folgt aus:
Die obige Implementierung ist nicht falsch, aber es gibt nur wenige Probleme:
-) Angenommen, Sie möchten in einer Entwicklungsumgebung an eine Textdatei gesendete SMS speichern, anstatt ein SMS-Gateway zu verwenden, um dies zu erreichen. Wir werden am Ende die konkrete Implementierung von (SMSService) durch eine andere Implementierung ändern. Wir verlieren an Flexibilität und müssen in diesem Fall den Code neu schreiben.
-) Wir werden am Ende die Verantwortlichkeiten der Klassen mischen, unser (UIHandler) sollte niemals etwas über die konkrete Implementierung von (SMSService) wissen, dies sollte außerhalb der Klassen unter Verwendung von "Schnittstellen" erfolgen. Wenn dies implementiert ist, können wir das Verhalten des Systems ändern, indem wir den (SMSService), der verwendet wird, gegen einen anderen Scheindienst austauschen, der dieselbe Schnittstelle implementiert. Dieser Dienst speichert SMS in einer Textdatei, anstatt sie an mobileNumber zu senden.
Um die oben genannten Probleme zu beheben, verwenden wir Schnittstellen, die von unserem (SMSService) und dem neuen (MockSMSService) implementiert werden. Grundsätzlich zeigt das neue Interface (ISMSService) dasselbe Verhalten beider Dienste wie der folgende Code:
Dann werden wir unsere (SMSService) -Implementierung ändern, um die (ISMSService) -Schnittstelle zu implementieren:
Jetzt können wir einen neuen Mock-up-Service (MockSMSService) mit völlig unterschiedlicher Implementierung über dieselbe Schnittstelle erstellen:
An dieser Stelle können wir den Code in (UIHandler) ändern, um die konkrete Implementierung des Dienstes (MockSMSService) wie folgt zu verwenden:
Wir haben viel Flexibilität erreicht und die Trennung von Bedenken in unseren Code implementiert, aber wir müssen noch eine Änderung an der Codebasis vornehmen, um zwischen den beiden SMS-Diensten zu wechseln. Wir müssen also Dependency Injection implementieren .
Um dies zu erreichen, müssen wir eine Änderung an unserem (UIHandler) -Klassenkonstruktor implementieren, um die Abhängigkeit durchzuleiten. Auf diese Weise kann der Code, der den (UIHandler) verwendet, bestimmen, welche konkrete Implementierung von (ISMSService) verwendet werden soll:
Jetzt ist das UI-Formular, das mit der Klasse (UIHandler) kommuniziert, dafür verantwortlich, zu übergeben, welche Implementierung der Schnittstelle (ISMSService) verwendet werden soll. Dies bedeutet, dass wir das Steuerelement invertiert haben. Der (UIHandler) ist nicht mehr dafür verantwortlich, zu entscheiden, welche Implementierung verwendet werden soll, der aufrufende Code. Wir haben das Inversion of Control- Prinzip implementiert, bei dem DI eine Art davon ist.
Der UI-Formularcode lautet wie folgt:
quelle
IOC (Inversion of Control) : Wenn Sie dem Container die Kontrolle geben, um eine Instanz des Objekts abzurufen, wird dies als Inversion of Control bezeichnet. Wenn Sie also kein Objekt mit dem neuen Operator erstellen, lassen Sie den Container dies für Sie tun.
DI (Dependency Injection) : Die Methode zum Injizieren von Eigenschaften in ein Objekt wird als Dependency Injection bezeichnet .
Wir haben drei Arten der Abhängigkeitsinjektion :
Die Feder unterstützt nur die Konstruktorinjektion und die Setter / Getter-Injektion .
quelle
Aber die Federdokumentation sagt, dass sie gleich sind.
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-introduction
In der ersten Zeile " IoC wird auch als Abhängigkeitsinjektion (DI) bezeichnet ".
quelle
IoC - Inversion of Control ist ein allgemeiner Begriff, unabhängig von der Sprache. Es werden eigentlich nicht die Objekte erstellt, sondern es wird beschrieben, auf welche Weise ein Objekt erstellt wird.
DI - Abhängigkeitsinjektion ist ein konkreter Begriff, bei dem wir Abhängigkeiten des Objekts zur Laufzeit mithilfe verschiedener Injektionstechniken bereitstellen, d. H. Setter Injection, Constructor Injection oder Interface Injection.
quelle
Die Umkehrung der Steuerung ist ein Entwurfsparadigma mit dem Ziel, den Zielkomponenten Ihrer Anwendung, die die Arbeit erledigen, mehr Kontrolle zu geben.
Die Abhängigkeitsinjektion ist ein Muster, mit dem Instanzen von Objekten erstellt werden, auf die sich andere Objekte stützen, ohne zur Kompilierungszeit zu wissen, welche Klasse zur Bereitstellung dieser Funktionalität verwendet wird.
Es gibt verschiedene grundlegende Techniken, um die Umkehrung der Steuerung zu implementieren. Diese sind:
1). Eine Konstruktorinjektion
2). Eine Setterinjektion
3). Eine Schnittstelleninjektion
quelle
DI und IOC sind zwei Entwurfsmuster, die sich hauptsächlich darauf konzentrieren, eine lose Kopplung zwischen Komponenten bereitzustellen , oder einfach eine Art und Weise, wie wir die herkömmlichen Abhängigkeitsbeziehungen zwischen Objekten entkoppeln, damit die Objekte nicht eng miteinander verbunden sind.
Mit den folgenden Beispielen versuche ich, beide Konzepte zu erklären.
Zuvor haben wir Code wie diesen geschrieben
Bei der Abhängigkeitsinjektion kümmert sich der Abhängigkeitsinjektor um die Instanziierung von Objekten
Der obige Prozess, die Steuerung einem anderen (zum Beispiel dem Container) für die Instanziierung und Injektion zu geben, kann als Inversion of Control bezeichnet werden, und der Prozess, bei dem der IOC-Container die Abhängigkeit für uns injiziert, kann als Abhängigkeitsinjektion bezeichnet werden.
IOC ist das Prinzip, bei dem der Steuerungsfluss eines Programms invertiert wird: Anstatt dass der Programmierer den Ablauf eines Programms steuert, steuert das Programm den Ablauf, indem es den Overhead für den Programmierer verringert. Der Prozess, den das Programm zum Einfügen der Abhängigkeit verwendet, wird als bezeichnet DI
Die beiden Konzepte arbeiten zusammen und bieten uns die Möglichkeit, viel flexibleren, wiederverwendbaren und gekapselten Code zu schreiben, was sie zu wichtigen Konzepten beim Entwerfen objektorientierter Lösungen macht.
Auch zum Lesen empfehlen.
Was ist Abhängigkeitsinjektion?
Sie können auch eine meiner ähnlichen Antworten hier überprüfen
Unterschied zwischen Inversion der Kontrolle und Abhängigkeitsinjektion
quelle
Inversion of Control ist ein generisches Entwurfsprinzip der Softwarearchitektur, mit dessen Hilfe wiederverwendbare, modulare Software-Frameworks erstellt werden können, die einfach zu warten sind.
Es ist ein Entwurfsprinzip, bei dem der Kontrollfluss von der generisch geschriebenen Bibliothek oder dem wiederverwendbaren Code "empfangen" wird.
Um es besser zu verstehen, sehen wir uns an, wie wir in früheren Codierungstagen codiert haben. In prozeduralen / traditionellen Sprachen steuert die Geschäftslogik im Allgemeinen den Fluss der Anwendung und "ruft" den generischen oder wiederverwendbaren Code / die Funktionen auf. In einer einfachen Konsolenanwendung wird mein Steuerungsfluss beispielsweise durch die Anweisungen meines Programms gesteuert, die möglicherweise die Aufrufe einiger allgemein wiederverwendbarer Funktionen umfassen.
Im Gegensatz dazu sind bei IoC die Frameworks der wiederverwendbare Code, der die Geschäftslogik "aufruft".
In einem Windows-basierten System ist beispielsweise bereits ein Framework zum Erstellen von UI-Elementen wie Schaltflächen, Menüs, Fenstern und Dialogfeldern verfügbar. Wenn ich die Geschäftslogik meiner Anwendung schreibe, werden die Ereignisse des Frameworks meinen Geschäftslogikcode aufrufen (wenn ein Ereignis ausgelöst wird) und NICHT das Gegenteil.
Obwohl der Code des Frameworks meine Geschäftslogik nicht kennt, kann er meinen Code trotzdem aufrufen. Dies wird durch Ereignisse / Delegaten, Rückrufe usw. erreicht. Hier ist die Steuerung des Flusses "invertiert".
Anstatt den Kontrollfluss von statisch gebundenen Objekten abhängig zu machen, hängt der Fluss vom Gesamtobjektgraphen und den Beziehungen zwischen verschiedenen Objekten ab.
Die Abhängigkeitsinjektion ist ein Entwurfsmuster, das das IoC-Prinzip zum Auflösen von Abhängigkeiten von Objekten implementiert.
In einfacheren Worten, wenn Sie versuchen, Code zu schreiben, erstellen und verwenden Sie verschiedene Klassen. Eine Klasse (Klasse A) kann andere Klassen (Klasse B und / oder D) verwenden. Klasse B und D sind also Abhängigkeiten der Klasse A.
Eine einfache Analogie wird ein Klassenauto sein. Ein Auto kann von anderen Klassen wie Motor, Reifen und mehr abhängen.
Die Abhängigkeitsinjektion schlägt vor, dass anstelle der abhängigen Klassen (hier Class Car), die ihre Abhängigkeiten erstellen (Class Engine und Klasse Tire), der Klasse die konkrete Instanz der Abhängigkeit injiziert werden sollte.
Lassen Sie uns mit einem praktischeren Beispiel verstehen. Bedenken Sie, dass Sie Ihren eigenen TextEditor schreiben. Unter anderem können Sie eine Rechtschreibprüfung durchführen, mit der der Benutzer die Tippfehler in seinem Text überprüfen kann. Eine einfache Implementierung eines solchen Codes kann sein:
Auf den ersten Blick sieht alles rosig aus. Der Benutzer wird Text schreiben. Der Entwickler erfasst den Text, ruft die CheckSpellings-Funktion auf und findet eine Liste der Tippfehler, die er dem Benutzer anzeigt.
Alles scheint gut zu funktionieren, bis eines schönen Tages ein Benutzer anfängt, Französisch im Editor zu schreiben.
Um mehr Sprachen unterstützen zu können, benötigen wir mehr SpellChecker. Wahrscheinlich Französisch, Deutsch, Spanisch usw.
Hier haben wir einen eng gekoppelten Code erstellt, wobei "English" SpellChecker eng mit unserer TextEditor-Klasse gekoppelt ist. Dies bedeutet, dass unsere TextEditor-Klasse vom EnglishSpellChecker abhängig ist oder mit anderen Worten, EnglishSpellCheker ist die Abhängigkeit für TextEditor. Wir müssen diese Abhängigkeit entfernen. Darüber hinaus benötigt unser Texteditor eine Möglichkeit, die konkrete Referenz einer Rechtschreibprüfung nach Ermessen des Entwicklers zur Laufzeit zu speichern.
Wie wir in der Einführung von DI gesehen haben, schlägt es vor, dass die Klasse mit ihren Abhängigkeiten injiziert werden sollte. Es sollte also in der Verantwortung des aufrufenden Codes liegen, alle Abhängigkeiten in die aufgerufene Klasse / den aufgerufenen Code einzufügen. So können wir unseren Code als umstrukturieren
In unserem Beispiel sollte die TextEditor-Klasse die konkrete Instanz des ISpellChecker-Typs erhalten.
Jetzt kann die Abhängigkeit in Constructor, eine öffentliche Eigenschaft oder eine Methode eingefügt werden.
Versuchen wir, unsere Klasse mit Constructor DI zu ändern. Die geänderte TextEditor-Klasse sieht ungefähr so aus:
Damit der aufrufende Code beim Erstellen des Texteditors den entsprechenden SpellChecker-Typ in die Instanz des TextEditors einfügen kann.
Den vollständigen Artikel können Sie hier lesen
quelle
IOC (Inversion of Control): Die Übergabe der Kontrolle an den Container zum Abrufen der Objektinstanz wird als Inversion of Control bezeichnet. Anstatt dass Sie ein Objekt mit einem neuen Operator erstellen , lassen Sie den Container dies für Sie tun.
DI (Dependency Injection): Die Übergabe der erforderlichen Parameter (Eigenschaften) von XML an ein Objekt (in POJO CLASS) wird als Dependency Injection bezeichnet.
quelle
IOC gibt an, dass externe Klassen die Klassen einer Anwendung verwalten, und externe Klassen bedeuten, dass ein Container die Abhängigkeit zwischen Anwendungsklassen verwaltet. Das Grundkonzept von IOC besteht darin, dass Programmierer Ihre Objekte nicht erstellen müssen, sondern beschreiben müssen, wie sie erstellt werden sollen.
Die Hauptaufgaben des IoC-Containers sind: Instanziieren der Anwendungsklasse. um das Objekt zu konfigurieren. um die Abhängigkeiten zwischen den Objekten zusammenzusetzen.
DI ist der Prozess zum Bereitstellen der Abhängigkeiten eines Objekts zur Laufzeit mithilfe der Setter-Injektion oder der Konstruktor-Injektion.
quelle
IOC (Inversion of Control) ist im Grunde ein Entwurfsmusterkonzept, bei dem Abhängigkeiten entfernt und entkoppelt werden, um den Fluss nichtlinear zu machen, und der Container / oder eine andere Entität die Bereitstellung von Abhängigkeiten verwalten kann. Es folgt tatsächlich Hollywoods Prinzip "Rufen Sie uns nicht an, wir rufen Sie an". Also die Unterschiede zusammenfassen.
Umkehrung der Kontrolle: - Es ist ein Oberbegriff, um die Abhängigkeiten zu entkoppeln und ihre Bereitstellung zu delegieren. Dies kann auf verschiedene Arten implementiert werden (Ereignisse, Delegaten usw.).
Abhängigkeitsinjektion: - DI ist ein Subtyp des IOC und wird durch Konstruktorinjektion, Setterinjektion oder Methodeninjektion implementiert.
Der folgende Artikel beschreibt dies sehr anschaulich.
https://www.codeproject.com/Articles/592372/Dependency-Injection-DI-vs-Inversion-of-Control-IO
quelle
Ich denke, die Idee kann klar demonstriert werden, ohne in objektorientierte Unkräuter zu geraten, die die Idee durcheinander zu bringen scheinen.
Wenn Sie den Kopf neigen und die Augen zusammenknicken, werden Sie feststellen, dass DI eine bestimmte Implementierung von IoC mit besonderen Bedenken ist. Anstatt Modelle und Verhaltensweisen in ein Anwendungsframework oder eine Operation höherer Ordnung einzufügen, fügen Sie Variablen in eine Funktion oder ein Objekt ein.
quelle
Beginnen wir mit D von SOLID und schauen uns DI und IoC aus Scott Milletts Buch "Professional ASP.NET Design Patterns" an:
Millett, C (2010). Professionelle ASP.NET-Entwurfsmuster. Wiley Publishing. 7-8.
quelle
// ICO, DI, vor 10 Jahren, so waren sie:
Jetzt mit Spring 3,4 oder spätestens wie unten
Insgesamt wird die Steuerung vom alten Konzept des gekoppelten Codes zu den Frameworks wie Spring umgekehrt, die das Objekt verfügbar machen. Soweit ich weiß, ist dies also IOC und Abhängigkeitsinjektion, wie Sie wissen, wenn wir das abhängige Objekt mit einem Konstruktor oder Setter in ein anderes Objekt injizieren. Injizieren bedeutet im Grunde, es als Argument zu übergeben. Im Frühjahr haben wir eine XML- und Annotations-basierte Konfiguration, in der wir das Bean-Objekt definieren und das abhängige Objekt mit dem Konstruktor- oder Setter-Injektionsstil übergeben.
quelle
Ich habe auf Dzone.com das beste Beispiel gefunden, das wirklich hilfreich ist, um den wirklichen Unterschied zwischen IOC und DI zu verstehen
Lesen Sie den vollständigen Artikel IOC und den vollständigen Artikel DI
quelle
1) DI ist Child-> obj hängt von parent-obj ab. Das Verb hängt davon ab, ist wichtig. 2) IOC ist Child-> obj unter einer Plattform durchführen. wo Plattform Schule, Hochschule, Tanzklasse sein könnte. Hier ist perform eine Aktivität mit unterschiedlichen Auswirkungen unter jedem Plattformanbieter.
praktisches Beispiel: `
`
-AB
quelle
Zu dieser Frage würde ich sagen, dass das Wiki bereits detaillierte und leicht verständliche Erklärungen geliefert hat. Ich werde hier nur das Wichtigste zitieren.
Implementierung von IoC
Wie für die Abhängigkeitsinjektion
quelle
Das IoC-Konzept wurde ursprünglich in der Ära der prozeduralen Programmierung gehört. Aus historischer Sicht sprach IoC daher über die Umkehrung des Eigentums an Kontrollfluss , dh wer die Verantwortung besitzt, die Funktionen in der gewünschten Reihenfolge aufzurufen - ob es sich um die Funktionen selbst handelt oder ob Sie sie in eine externe Entität umkehren sollten.
Als jedoch die OOP auftauchte, wurde im OOP-Kontext über IoC gesprochen, wobei Anwendungen neben dem Kontrollfluss auch die Objekterstellung und ihre Beziehungen betreffen. Solche Anwendungen wollte umkehren , das Eigentum an Objekterstellungs (statt Kontrollfluss) und benötigt einen Behälter, der für die Objekterstellung, Objektlebenszyklus und Injizieren Abhängigkeiten der Anwendung verantwortlich ist , Objekte dadurch eliminiert Anwendungsobjekte von der Erstellung anderen konkreten Objekt.
In diesem Sinne ist DI nicht dasselbe wie Io C , da es nicht um Kontrollfluss geht, sondern um eine Art Io * , dh Umkehrung des Eigentums an der Objekterstellung.
Was ist falsch daran, DI und IoC zu erklären?
quelle
IoC alias Inversion of Control bezieht sich auf die Steuerung des Erstellens von Instanzen, die vom Spring-Container ausgeführt werden. Das Steuerelement zum Erstellen und Erstellen von Objekten wird vom Container übernommen. Der Container erstellt die Objekte und fügt sie in unsere Anwendung ein.
quelle