Dependency Injection (DI) ist eine von Design Patterns, die das grundlegende Merkmal von OOP nutzt - die Beziehung eines Objekts zu einem anderen Objekt. Während Vererbung ein Objekt erbt, um ein komplexeres und spezifischeres anderes Objekt zu tun, erstellt Beziehung oder Assoziation einfach einen Zeiger auf ein anderes Objekt von einem Objekt mit Attribut. Die Stärke von DI liegt in der Kombination mit anderen Merkmalen von OOP wie Schnittstellen und dem Verstecken von Code. Angenommen, wir haben einen Kunden (Abonnenten) in der Bibliothek, der der Einfachheit halber nur ein Buch ausleihen kann.
Schnittstelle des Buches:
package com.deepam.hidden;
public interface BookInterface {
public BookInterface setHeight(int height);
public BookInterface setPages(int pages);
public int getHeight();
public int getPages();
public String toString();
}
Dann gibt es viele Arten von Büchern; eine davon ist die Belletristik:
package com.deepam.hidden;
public class FictionBook implements BookInterface {
int height = 0; // height in cm
int pages = 0; // number of pages
/** constructor */
public FictionBook() {
// TODO Auto-generated constructor stub
}
@Override
public FictionBook setHeight(int height) {
this.height = height;
return this;
}
@Override
public FictionBook setPages(int pages) {
this.pages = pages;
return this;
}
@Override
public int getHeight() {
// TODO Auto-generated method stub
return height;
}
@Override
public int getPages() {
// TODO Auto-generated method stub
return pages;
}
@Override
public String toString(){
return ("height: " + height + ", " + "pages: " + pages);
}
}
Jetzt können Abonnenten eine Verbindung zu dem Buch herstellen:
package com.deepam.hidden;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Subscriber {
BookInterface book;
/** constructor*/
public Subscriber() {
// TODO Auto-generated constructor stub
}
// injection I
public void setBook(BookInterface book) {
this.book = book;
}
// injection II
public BookInterface setBook(String bookName) {
try {
Class<?> cl = Class.forName(bookName);
Constructor<?> constructor = cl.getConstructor(); // use it for parameters in constructor
BookInterface book = (BookInterface) constructor.newInstance();
//book = (BookInterface) Class.forName(bookName).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return book;
}
public BookInterface getBook() {
return book;
}
public static void main(String[] args) {
}
}
Alle drei Klassen können für ihre eigene Implementierung ausgeblendet werden. Jetzt können wir diesen Code für DI verwenden:
package com.deepam.implement;
import com.deepam.hidden.Subscriber;
import com.deepam.hidden.FictionBook;
public class CallHiddenImplBook {
public CallHiddenImplBook() {
// TODO Auto-generated constructor stub
}
public void doIt() {
Subscriber ab = new Subscriber();
// injection I
FictionBook bookI = new FictionBook();
bookI.setHeight(30); // cm
bookI.setPages(250);
ab.setBook(bookI); // inject
System.out.println("injection I " + ab.getBook().toString());
// injection II
FictionBook bookII = ((FictionBook) ab.setBook("com.deepam.hidden.FictionBook")).setHeight(5).setPages(108); // inject and set
System.out.println("injection II " + ab.getBook().toString());
}
public static void main(String[] args) {
CallHiddenImplBook kh = new CallHiddenImplBook();
kh.doIt();
}
}
Es gibt viele verschiedene Möglichkeiten, die Dependency Injection zu nutzen. Es ist möglich, es mit Singleton usw. zu kombinieren, aber im Grunde ist es nur eine Assoziation, die durch das Erstellen von Attributen eines Objekttyps innerhalb eines anderen Objekts realisiert wird. Die Nützlichkeit liegt einzig und allein in der Eigenschaft, dass der Code, den wir immer wieder schreiben sollen, immer schon für uns vorbereitet und erledigt ist. Deshalb ist DI so eng mit Inversion of Control (IoC) verknüpft, was bedeutet, dass unser Programm die Kontrolle an ein anderes laufendes Modul weitergibt, das Injektionen von Beans in unseren Code vornimmt. (Jedes Objekt, das injiziert werden kann, kann signiert oder als Bean betrachtet werden.) In Spring wird dies zum Beispiel durch das Erstellen und Initialisieren von Anwendungskontext Container, der diese Arbeit für uns erledigt. Wir erstellen in unserem Code einfach den Context und rufen die Initialisierung der Beans auf. In diesem Moment ist die Injektion automatisch erfolgt.
0 Stimmen
Siehe meine Diskussion über Dependency Injection Hier .
44 Stimmen
Ich stimme den Kommentaren zu den Links zu. Ich kann verstehen, dass Sie vielleicht auf jemand anderen verweisen wollen. Aber fügen Sie zumindest hinzu, warum Sie sie verlinken und was diesen Link besser macht als die anderen Links, die ich mit Google finden könnte
0 Stimmen
@AR: Technisch gesehen, ist Dependency Injection no eine besondere Form von IoC. Vielmehr ist IoC eine Technik, die zur Bereitstellung von Dependency Injection verwendet wird. Es können auch andere Techniken für die Dependency Injection verwendet werden (obwohl IoC die einzige ist, die häufig verwendet wird), und IoC wird auch für viele andere Probleme verwendet.
157 Stimmen
Was die Links betrifft, so ist zu bedenken, dass sie oft auf die eine oder andere Weise verschwinden. Die Zahl der toten Links in SO-Antworten steigt. Egal, wie gut der verlinkte Artikel ist, er nützt nichts, wenn man ihn nicht finden kann.
0 Stimmen
Vojta Jina über Dependency Injection youtu.be/_OGGsf1ZXMs . Der erste Teil.
0 Stimmen
Ein Überblick über Dependency Injection und ihre Beziehung zu anderen OOP-Prinzipien: deviq.com/dependency-injection
0 Stimmen
Hier ist ein Anwendungsbeispiel ohne DI: tugay.biz/2017/05/standalone-jpa-beispiel-mit-hibernate.html und dasselbe mit DI: tugay.biz/2017/05/add-c3p0-to-previous-example.html