Ich habe eine anständige Menge an OOP mit verschiedenen Sprachen, bin aber ziemlich neu in Java.
Ich lese viele Tutorials durch, in denen eine große Anzahl von Objekten im Code einer Klasse erstellt wird, und ich versuche, sie zu durchlaufen, aber in den Tutorials, die Dependency Injection ausführen, Versionen der Klassen zu erstellen, anstatt alle zu instanziieren Klassen selbst.
Aber Java ist nicht wie andere Sprachen, in denen ich so ziemlich alles als Objekt verwendet habe. Wenn ich buchstäblich alles injizieren würde, wäre das Ergebnis sehr chaotisch und schwer zu verfolgen.
Natürlich würden Sie keine String-Objekte injizieren, und ich vermute, es gibt andere Objekte, die Sie nicht injizieren würden, aber ich bin mir nicht sicher, wohin die Linie führen soll. Ab wann ist DI nicht mehr das Richtige und wann wird es zur Belastung? Wie entscheiden Sie pragmatisch, was injiziert und was nur instanziiert werden soll?
Zu Ihrer Information, die Tutorials, die ich mache, sind http://edn.embarcadero.com/article/31995 und http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html zum Erstellen eines einfachen Clients und Server. Ich kopiere sie jedoch nicht Zeile für Zeile, sondern versuche, äquivalente Klassen zu erstellen, die den Best Practices entsprechen
Antworten:
In .Net (was in dieser Hinsicht ähnlich ist, dass alles ein Objekt ist) verwende ich DI hauptsächlich für meine Domänenobjekte (Entitäten, Repositorys und Dienste) und Anwendungsobjekte (Controller, Ansichtsmodelle), sodass Repos / Dienste in den Controller eingefügt werden / Modelle und ähnliches anzeigen. Dies bedeutet, dass meine Geschäfts- und Anwendungslogik vollständig testbar ist. Dies ist der Hauptgrund, warum ich DI verwende.
Grundsätzlich handelt es sich bei den Objekten, in die Sie Inhalte injizieren und injizieren, hauptsächlich um Objekte, die für die von Ihnen erstellte Lösung spezifisch sind. Wenn ein Objekt in der Sprache oder im Framework "native" ist (wie .Net), muss es wahrscheinlich nicht injiziert werden. Viele Objekte benötigen eine Zeichenfolge, um Daten darzustellen, und eine Zeichenfolge ist im Grunde eine "Sprachfunktion", die nicht spezifisch für Ihre Domäne ist. Das Gleiche gilt für Aufzählungen, Listen, Arrays und viele andere Dinge, die sich nicht ändern müssen, wenn Sie Ihre Klasse isoliert vom Rest des Systems ausführen möchten.
Das Wichtigste ist die Kopplung zwischen Ihren Domänen- / Anwendungsklassen. Wenn ein Objekt keine enge Kopplung einführt, ist es normalerweise sicher, es einfach zu erstellen. Eine Möglichkeit, die Kopplung zu überprüfen, besteht darin, zu versuchen, die Methoden in einer Klasse isoliert auszuführen (was im Grunde ein Unit-Test ist). Was DI-ed sein muss, sind alle Abhängigkeiten, die Sie verspotten müssen, um sicherzustellen, dass die Klasse, die Sie testen, wirklich isoliert vom System ausgeführt wird.
quelle
Erstens ist es in Ordnung, das neue Schlüsselwort wirklich zu verwenden! DI ist eine fantastische Technik, aber es besteht die Versuchung, sie zu überbeanspruchen. Zeiten, in denen Sie DI verwenden möchten, sind:
Testdoppel - Oft möchten Sie bei Komponententests eine Ressource eines Drittanbieters verspotten / testen, da Sie diese Ressource eines Drittanbieters nicht aufrufen möchten (z. B. eine vollständige Oracle-Datenbank). Anstatt beispielsweise eine neue Datenbankverbindung zur großen Oracle-Datenbank zu erstellen, möchten Sie diese Verbindung möglicherweise durch eine Verbindung zu einer HSQL-Verbindung (in der Speicherdatenbank) ersetzen.
Wenn Sie den Bereich (~ Lebensdauer) dieses Objekts steuern möchten und der natürliche Lebenszyklus von Java-Objekten für Sie nicht funktioniert. Viele Java-basierte DI-Frameworks ermöglichen dies.
Wenn Sie Singletons wollen.
Immer wenn Sie glauben, eine Fabrik, einen Service Locator oder ähnliches zu benötigen. Dies schließt ein, wenn Sie verschiedene Fabriken benötigen (selten, aber es passiert).
Zu anderen Zeiten erstellen Sie einfach ein neues Objekt. Wenn Sie Zweifel haben, erstellen Sie ein neues Objekt. Sie können es jederzeit ändern, wenn Sie später die Notwendigkeit sehen :-).
quelle
Aus Wikipedia :
Sie sollten keine Zeichenfolgen einfügen müssen, sondern können sie einfach als Parameter an die entsprechende Methode übergeben. Sie sollten keine Daten einfügen müssen, die aus der Konfiguration stammen.
Gute Komponententests helfen Ihnen bei der Lokalisierung von Fehlern. Daher sollten Sie Ihren Code unabhängig von anderen Codeeinheiten testen. DI kann Ihnen dabei helfen.
quelle
Im Allgemeinen finde ich, dass eine Klasse immer nur
new
aus einer anderen Klasse stammen sollte.Dies liegt daran, dass jedes verwendete Objekt
new
alle Abhängigkeiten der von ihm erstellten Objekte einfügen muss, sobald Sie die Abhängigkeitsinjektion durchlaufen haben. Dies bedeutet, dass das übergeordnete Objekt auch alle diese Abhängigkeiten kennen muss. WennA
hat eine Abhängigkeit aufB
undC
erzeugtA
Instanzen mitnew
dannC
automatisch eine Abhängigkeit von haben mussB
, auch wennC
nie benutztB
direkt. Erstens verstößt dies gegen die Trennung von Bedenken, es sei dennC
, die einzige Aufgabe besteht darin,A
s zu erstellen . Andernfalls entsteht ein Problem, wenn Sie jemals eine Abhängigkeit hinzufügen möchten,A
da alle Dinge, die sie erstellen, jetzt dieselbe Abhängigkeit hinzufügen müssen. Damit sollten sie sich wirklich nicht befassen. Es ist besser zu habenC
Deklarieren Sie eine Abhängigkeit vonAFactory
undAFactory
haben Sie eine Abhängigkeit vonB
. Dann können SieA
allen gewünschten Abhängigkeiten hinzufügen und müssen diese nurAFactory
noch ändern.quelle
"Ab wann ist DI nicht mehr das Richtige und wann wird es zur Last? ..."
Zuallererst mag ich DI und benutze es sehr oft, also versteh mich nicht falsch
DI ist großartig für die Serverseite, aber die Spiele ändern sich insgesamt, wenn es um die Gui-Programmierung geht. Zum Beispiel habe ich Guice in eine vorhandene GUI-App integriert, die in Swing entwickelt wurde
Wie gehe ich mit verschachtelten Abhängigkeiten um?
Angenommen, Sie müssen auf einige Abhängigkeiten in einer tief verschachtelten Klasse zugreifen. Sie können DI auf eine der folgenden Arten verwenden:
Wie wäre es, wenn Sie Objekt mit neuen () (weil das Objekt Bedarf zur Laufzeit erstellt werden , abhängig von einigen criteris) und wollen es in den Behälter registrieren (Guice Objekte mit neuen nicht Griffe () erstellt erstellt werden soll, das ist gut )? Jetzt müssen Sie sich wieder auf den Container konzentrieren, anstatt neue Funktionen in Ihrer App zu entwickeln.
Abschließende Worte In einigen Fällen können Sie mit DesignPatterns + kreativem Denken und gutem Architekturdesign Situationen vermeiden, in denen das Geld klein ist und die Probleme durch die Einführung von DI groß sind
quelle