Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Hi,
ich habe schon das ganze Netz abgesurft bzgl. CDI und den Vorteil nicht "new" zu verwenden. Überall wird nur die Technik mit "@Inject" erklärt, aber den eigentlichen Vorteil kann ich nicht erkennen? Wieso habe ich mit dem injezieren keine harte Kopplung?
Weil du dich mit der zweiten Lösung auf eine konkrete Implementation festlegst, wobei es vermutlich in deinem Beispiel völlig egal ist, weil es offenbar nur den "ImageFileEditor" gibt.
Logischer wird es z.B. so:
@Inject
EditorInterface editor;
Dann kann "editor" alles sein, was das Interface implementiert.
Mal ein bisschen allgemeiner, ganz ohne den "syntactic sugar" mit der @Inject Annotation und all dem, was das CDI Framework noch drumherum an Magie leistet, vergleiche doch einfach mal die beiden Ansätze, und was das konkret für Klasse A bedeutet.
Ohne Dependency Injection:
Java:
class A {
B dependency = new B();
}
Mit Dependency Injection:
Java:
class A {
B dependency;
void setB(B someB) {
this.dependency = someB;
}
}
Bei der zweiten Variante muss A die konkrete Implementierung von B gar nicht kennen. A muss nichts darüber wissen, wie B instanziiert werden kann. Je nach Kontext kannst du A sogar mit einer anderen Implementierung von B verwenden.
Die höhere Flexibilität erkaufst du dir doch eine höhere Komplexität deiner Software. Du brauchst z.B. "jemanden", der sich darum kümmert, dass A zur richtigen Zeit mit dem richtigen B versorgt wird.
Das ganze bringt aber doch auch dann nur Vorteile, wenn A überhaupt nichts mit B macht, sondern dieses nur „Weiterreicht“. In dem Moment wo A eine Methode von B benutzt muss er die Implementierung ja wieder kennen. Und dann ist es auch egal ob er B selber instanziert oder nicht
@offi genau das ist der Punkt: CDI enthält DI + magic. Wie Du schon gesehen hast, ist für DI kein Framework notwendig.
Insofern wäre die Frage also, ob und, falls ja, welchen Vorteil ein DI-Framework gegenüber DI hat. Das wiederum ist pauschal nicht beantwortbar.
Grundsätzlich kann man sagen: kein Framework, keine Magie. Und man darf es durchaus als Vorteil ansehen, wenn man auf den ersten Blick sieht, was Sache ist. Umgekehrt bedeutet es aber nicht automatisch, dass ein DI-Framework alles verschleiern muss.
Das Beispiel von @stg mit CDI könnte z. B. so aussehen:
Java:
class A {
@Inject
private B dependency;
}
Was passiert hier? Wenn via CDI ein A-Objekt erzeugt wird, wird automatisch ein B-Objekt injiziert (magic). Ob es sich dabei um eine neue B-Instanz handelt, hängt vom Scope ab (magic). Welche konkrete Klasse instantiiert wird, ist auch nicht unbedingt sofort erkennbar (magic).
Von außen ist somit nicht sichtbar, dass ein A ein B braucht -> oft nix gut. Dagegen sieht man bei
Java:
class A {
private B dependency;
public A(@Inject B b) {
dependency = b;
}
}
sofort, dass A ein B benötigt. Außerdem kann man in dem Fall die DI auch ohne das Framework vornehmen.
In dem Moment wo A eine Methode von B benutzt muss er die Implementierung ja wieder kennen. Und dann ist es auch egal ob er B selber instanziert oder nicht
interface Zahlengenerator {
int naechsteZahl();
}
class A {
private Zahlengenerator generator;
public A(Zahlengenerator g) { generator = g; }
public void print(int anzahl) {
for (int i = 0; i < anzahl; i++) {
System.out.println(generator.naechsteZahl());
}
}
}
A arbeitet hier einfach mit einer Instanz, die eine Zahlengenerator-Schnittstelle zur Verfügung stellt. A kennt aber die Implementierung nicht. Man kann A mit jeglichem Zahlengenerator füttern, z. B. einem EinfacherZahlenGenerator, PrimzahlenGenerator, ZufallszahlenGenerator usw.
....und im Rahmen dazugehöriger Unit-Tests injizierst du einen "Zufallsgenerator", der deterministisch immer die gleichen Zufallszahlen liefert.
(Du willst ja auch A testen und nicht die Generierung von Zufallszahlen, also ist das vollkommen in Ordnung)