Wie kann man einem 5-Jährigen die Abhängigkeitsinjektion erklären? [geschlossen]

208

Was ist ein guter Weg, um die Abhängigkeitsinjektion zu erklären ?

Ich habe mehrere Tutorials bei Google gefunden, aber keines davon würde davon ausgehen, dass der Leser nur ein Java-Anfänger ist. Wie würden Sie dies einem Anfänger erklären?

user198313
quelle
72
Klingt so, als würde das Kind ein hartes Leben führen ...
ire_and_curses
24
Beginnen Sie mit "Es war einmal ....."
Martin
1
Sprechen wir über einen Java-Anfänger oder einen wörtlichen Fünfjährigen?
Drew
2
# Abhängigkeitsinjektion # hängt nicht vom Alter des Lernenden ab. Es ist für jeden gleich
Rakesh Juyal
2
Rakesh: Das Einführungsvideo zu JavaOne 2009 basiert auf der Prämisse, dass selbst ein 13-jähriger Java-Entwickler sein kann, da Java "überall" und "einfach" ist.
Esko

Antworten:

789

Ich gebe Ihnen eine Abhängigkeitsinjektion für Fünfjährige.

Wenn Sie Dinge selbst aus dem Kühlschrank holen, können Sie Probleme verursachen. Sie könnten die Tür offen lassen, Sie könnten etwas bekommen, das Mama oder Papa nicht wollen, dass Sie haben. Vielleicht suchen Sie sogar nach etwas, das wir nicht einmal haben oder das abgelaufen ist.

Was Sie tun sollten, ist zu sagen: "Ich brauche etwas zum Mittagessen zu trinken", und dann werden wir sicherstellen, dass Sie etwas haben, wenn Sie sich zum Essen hinsetzen.

John Munsch
quelle
93

Was ist damit?

Wenn Sie eine Klasse haben Employeeund dieser Mitarbeiter eine Address hat, können Sie die EmployeeKlasse wie folgt definieren lassen:

class Employee {
    private Address address;

    // constructor 
    public Employee( Address newAddress ) {
        this.address = newAddress;
    }

    public Address getAddress() {
    return this.address;
    }
    public void setAddress( Address newAddress ) {
        this.address = newAddress;
    }
}

Bisher sieht alles gut aus.

Dieser Code zeigt eine HAS-A- Beziehung zwischen dem Mitarbeiter und seiner Adresse, das ist in Ordnung.

Diese HAS-A- Beziehung hat nun eine Abhängigkeit zwischen ihnen geschaffen. Das Problem liegt beim Konstruktor.

Jedes Mal, wenn EmployeeSie eine AddressInstanz erstellen möchten, benötigen Sie eine Instanz:

 Address someAddress = ....
 Employee oscar = new Employee( someAddress ); 

Das Arbeiten auf diese Weise wird besonders dann problematisch, wenn Sie Unit-Tests durchführen möchten.

Das Hauptproblem kommt , wenn Sie ein bestimmtes Objekt testen müssen, müssen Sie eine Instanz von anderem Objekt erstellen, und höchstwahrscheinlich benötigen Sie eine Instanz noch zu schaffen anderen Objekt , das zu tun. Die Kette kann unhandlich werden.

Um dies zu vermeiden, können Sie den Konstruktor folgendermaßen ändern:

  public Employee(){
  }

Verwenden eines Konstruktors ohne Argumente.

Dann können Sie die Adresse festlegen, wann immer Sie möchten:

 Address someAddress = ....
 Employee oscar = new Employee();
 oscar.setAddress( someAddress ); 

Dies kann ein Drag sein, wenn Sie mehrere Attribute haben oder wenn die Objekte schwer zu erstellen sind.

Denken Sie jedoch darüber nach, sagen wir, Sie fügen das DepartmentAttribut hinzu:

  class Employee {
      private Address address;
      private Department department;

  ....

Wenn Sie 300 Mitarbeiter haben und alle dieselbe Abteilung haben müssen und diese Abteilung auch von einigen anderen Objekten (wie der Liste der Unternehmensabteilungen oder den Rollen der einzelnen Abteilungen usw.) gemeinsam genutzt werden muss, sind Sie hier genau richtig Es fällt Ihnen schwer, das DepartmentObjekt sichtbar zu machen und es über das gesamte Netzwerk von Objekten zu teilen.

Worum es bei der Abhängigkeitsinjektion geht, damit Sie diese Abhängigkeiten in Ihren Code " einfügen" können. In den meisten Frameworks können Sie dies tun, indem Sie in einer externen Datei angeben, welches Objekt injiziert werden soll.

Angenommen, eine Eigenschaftendatei für einen fiktiven Abhängigkeitsinjektor:

  #mock employee
  employee.address = MockAddress.class
  employee.department = MockDepartment.class

  #production setup 
  employee.address = RealAddress.class
  employee.department = RealDepartment.class

Sie definieren, was für ein bestimmtes Szenario injiziert werden soll.

Das Dependency Injector-Framework legt die richtigen Objekte für Sie fest, sodass Sie weder codieren setAddressnoch codieren müssen setDepartment. Dies würde entweder durch Reflexion oder durch Codegenerierung oder andere Techniken erfolgen.

Wenn Sie das nächste Mal die EmployeeKlasse testen müssen, können Sie Mock Addressund DepartmentsObjekte einfügen, ohne den gesamten Satz / Abruf für alle Ihre Tests codieren zu müssen. Noch besser ist, dass Sie Real- Address und DepartmentObjekte in den Produktionscode einfügen können und trotzdem das Vertrauen haben, dass Ihr Code wie getestet funktioniert.

Das ist ziemlich viel.

Trotzdem denke ich nicht, dass diese Erklärung für einen 5-Jährigen geeignet ist, wie Sie es gewünscht haben.

Ich hoffe, Sie finden es immer noch nützlich.

OscarRyz
quelle
3
Oder: Dependency Injection ist , wenn Sie etwas Einstellung der Abhängigkeiten für Sie. Dies ist normalerweise ein Rahmen. :)
OscarRyz
2
eine sehr kluge in der Tat.
OscarRyz
24

Wenn Sie eine Klasse schreiben, können Sie natürlich auch andere Objekte verwenden. Möglicherweise haben Sie beispielsweise eine Datenbankverbindung oder einen anderen Dienst, den Sie verwenden. Diese anderen Objekte (oder Dienste) sind Abhängigkeiten. Der einfachste Weg, den Code zu schreiben, besteht darin, diese anderen Objekte zu erstellen und zu verwenden. Dies bedeutet jedoch, dass Ihr Objekt eine unflexible Beziehung zu diesen Abhängigkeiten hat: Unabhängig davon, warum Sie Ihr Objekt aufrufen, werden dieselben Abhängigkeiten verwendet.

Eine leistungsfähigere Technik besteht darin, Ihr Objekt erstellen und ihm Abhängigkeiten zur Verfügung stellen zu können. Sie können also eine zu verwendende Datenbankverbindung erstellen und diese dann an Ihr Objekt übergeben. Auf diese Weise können Sie Ihr Objekt mit unterschiedlichen Abhängigkeiten zu unterschiedlichen Zeiten erstellen, wodurch Ihr Objekt flexibler wird. Dies ist die Abhängigkeitsinjektion, bei der Sie die Abhängigkeiten in das Objekt "injizieren".

Übrigens: In dem modernen Präsentationsstil, bei dem Flickr-Fotos zur Veranschaulichung von Konzepten verwendet werden, könnte dies durch einen Süchtigen veranschaulicht werden, der sich mit Drogen beschießt. Oh, warte, das ist Injektionsabhängigkeit ... OK, sorry, schlechter Witz.

Ned Batchelder
quelle
10

Ich kenne keine vereinfachten Tutorials, aber ich kann Ihnen eine Version mit fast 25 250 Wörtern oder weniger geben:

Bei der Abhängigkeitsinjektion konfiguriert ein Objekt seine eigenen Komponenten nicht basierend auf bereits bekannten Dingen, sondern das Objekt wird durch eine übergeordnete Logik konfiguriert und ruft dann Komponenten auf, über die es keine Vorkenntnisse eingebaut hat. Die Idee ist, das Objekt mehr zu einer Komponente und weniger zu einer Anwendung zu machen und Konfigurationsaufgaben auf einer höheren Ebene zu verschieben. Dies erhöht die Wahrscheinlichkeit, dass das Objekt in Zukunft oder mit einer anderen Konfiguration nützlich ist.

Es ist besser zum Testen, es ist besser, wenn es Zeit ist, die Anwendung zu überarbeiten. Eine typische Implementierung legt die Konfiguration in XML ab und verwendet ein Framework zum dynamischen Laden von Klassen.

DigitalRoss
quelle
7

Wenn Sie einen neuen Nintendo erhalten, können Sie einfach die Tasten und den Touchscreen verwenden, um Spiele zu spielen.

Aber in der Nintendo-Fabrik müssen sie wissen, wie man eine zusammenstellt.

Wenn die klugen Leute in der Fabrik einen Nintendo DS herausbringen, wird es innen anders sein, aber Sie werden immer noch wissen, wie man es benutzt.

WW.
quelle
5
Das klingt eher nach einer Beschreibung von Schnittstellen oder Polymorphismus, aber ich gebe Ihnen die Ehre , für einen 5-Jährigen tatsächlich verständlich zu sein.
Natix