Files
java-design-patterns/localization/de/dependency-injection
Stefan SiebersandGitHub cd4753a660 docs: Improve existing German READMEs and add new ones (#3444)
* docs: reformulate text, add links to further languages and paragraph about the book in central README.md
(#2275)

* docs: shorten text for link to payhip
(#2275)

* docs: reformulate german translation for Abstract Document
(#2275)

* Create folder for Abstract Factory

* Create README.md for Abstract Document

* Translate README.md for Abstract Document to German

* correct typo

* docs: add class diagrams for all patterns
(#2275)

* docs: add missing words in abstract-factory.README.md
(#2275)

* docs: Create German README.md for Active Object

#2275
first text part

* docs: finish German translation of README.md for Active Object

* docs: translate actor-model into German

#2295

* docs: add German translation for Acyclic Visitor

#2295

* correct typo

* docs: Translate Singleton into German

#2295

* docs: Translate Prototype into German

#2295

* Delete localization/de/Abstract Factory

* insert line break

* correct typos in actor-model

* realignment of java code block

* docs: translate Adapter Pattern into German

#2295

* Update README.md

change 'lizenz' to 'Lizenz' in badge

* Update README.md

translate 'benefits' and 'trade-offs'

* remove additional bullet point after line break

* correct indentation

* docs: translate Dependency Injection into German

#2295

* docs: translate Bridge into German

#2295

* correct typos

* docs: Translate Builder into German

* delete english text

* little changes in formulation

* Update README.md

change link to image

* docs: remove spanish files
(#2275)

* docs: remove non-translated patterns
(#2275)

* Create README.md

docs: Translate Step Builder into German
#2275

* Create README.md

docs: Translate Fluent Interface into German
#2275

* eager is eifrig, not gierig

* Translate Chain of Responsibility into German

#2275
2026-06-03 20:20:05 +03:00
..

shortTitle, category, language, tag
shortTitle category language tag
Dependency Injection Creational de
Decoupling
Dependency management
Inversion of control

Alternativbezeichnungen

  • Inversion of Control (IoC)
  • Dependency Inversion

Zweck

Die Erzeugung der in einem Objekt benötigten Abhängigkeiten soll von der Verwendung entkoppelt werden. So wird der Code flexibler und testbarer.

Detaillierte Erklärung

Beispiel aus dem echten Leben

Stellen Sie sich edles Restaurant vor, in dem der Koch diverse Zutaten für das Essen braucht. Er geht nicht für jede Zutat einzeln zu deren Hersteller, sondern bedient sich eines zuverlässigen Lieferanten, der ihm jeden Tag die Produkte frisch vom jeweiligen Hersteller besorgt. So kann er sich aufs Kochen konzentrieren und muss sich nicht mehr um den Einkauf kümmern.

Im Dependency-Injection-Pattern fungiert der Lieferant als "Injektor", der die nötigen Abhängigkeiten (Zutaten) dem "Objekt" Koch zur Verfügung stellt. Der Koch kann die Zutaten verwenden, ohne deren Ursprung kennen zu müssen. Die Beschaffung und Verwendung der Abhängigkeiten sind also klar getrennt. Mit diesem Ansatz werden Effizienz, Flexibilität und Wartungsfreundlichkeit in der Küche verbessert, ebenso wie in einem Softwaresystem.

In einfachen Worten

Dependency Injection trennt die Beschaffung der Abhängigkeiten vom eigenen Verhalten des Verwenders.

Wikipedia sagt

In der Softwareentwicklung ist Dependency Injection eine Technik, mit der ein Objekt andere Objekte zugewiesen bekommt, die es benötigt. Diese anderen Objekte nennt man Abhängigkeiten (Dependencies).

Ablaufdiagramm

Dependency Injection sequence diagram

Programmbeispiel

Der alte Hexenmeister möchte hin und wieder seine Pfeife stopfen und Tabak rauchen. Dabei will er aber nicht von einer einzigen Tabakmarke abhängig sein, sondern die Marke wechseln können.

Definieren wir also zunächst die Schnittstelle Tobacco und konkrete Klassen für die Marken.


public abstract class Tobacco {

    public void smoke(Wizard wizard) {
        LOGGER.info("{} smoking {}", wizard.getClass().getSimpleName(),
                this.getClass().getSimpleName());
    }
}

public class SecondBreakfastTobacco extends Tobacco {
}

public class RivendellTobacco extends Tobacco {
}

public class OldTobyTobacco extends Tobacco {
}

Als nächstes die Wizard-Klassenhierarchie.

public interface Wizard {

    void smoke();
}

public class AdvancedWizard implements Wizard {

    private final Tobacco tobacco;

    public AdvancedWizard(Tobacco tobacco) {
        this.tobacco = tobacco;
    }

    @Override
    public void smoke() {
        tobacco.smoke(this);
    }
}

Schließlich sehen wir, wie leicht es ist, dem Hexenmeister jede beliebige Tabakmarke zu geben.

public static void main(String[] args) {
    var simpleWizard = new SimpleWizard();
    simpleWizard.smoke();

    var advancedWizard = new AdvancedWizard(new SecondBreakfastTobacco());
    advancedWizard.smoke();

    var advancedSorceress = new AdvancedSorceress();
    advancedSorceress.setTobacco(new SecondBreakfastTobacco());
    advancedSorceress.smoke();

    var injector = Guice.createInjector(new TobaccoModule());
    var guiceWizard = injector.getInstance(GuiceWizard.class);
    guiceWizard.smoke();
}

Prorammausgabe:

11:54:05.205 [main] INFO com.iluwatar.dependency.injection.Tobacco -- SimpleWizard smoking OldTobyTobacco
11:54:05.207 [main] INFO com.iluwatar.dependency.injection.Tobacco -- AdvancedWizard smoking SecondBreakfastTobacco
11:54:05.207 [main] INFO com.iluwatar.dependency.injection.Tobacco -- AdvancedSorceress smoking SecondBreakfastTobacco
11:54:05.308 [main] INFO com.iluwatar.dependency.injection.Tobacco -- GuiceWizard smoking RivendellTobacco

Verwendung

  • Wenn die Kopplung zwischen den Klassen reduziert und die Modularität der Anwendung erhöht werden soll
  • In Szenarien, wo die Objekterzeugung komplex ist oder sonst von der Verwendung der Klasse getrennt werden soll.
  • In Anwendungen, die einfacheres Texten durch Mocks oder Stubs benötigen.
  • In Frameworks oder Bibliotheken, die den Lebenszyklus von Objekten managen, wie Spring oder Jakarta EE (früher Java EE).

Reale Anwendungen in Java

  • Frameworks wie Spring, Jakarta EE und Google Guice verwenden Dependency Injection (DI) ausgiebig, um Lebenszyklen und Abhängigkeiten zu verwalten.
  • Desktop- und Webanwendungen, die eine flexible Architektur mit leicht austauschbaren Komponenten benötigen.

Vor- und Nachteile

Vorteile:

  • Verbessert die Modularität und Trennung von Zuständigkeiten.
  • Vereinfacht Unit-Tests durch leichtes Mocken von Abhängigkeiten.
  • Verbessert Flexibilität und Wartbarkeit durch Förderung von loser Kopplung.

Nachteile:

  • Kann Konfiguration verkomplizieren, vor allem in großen Projekten.
  • Entwickler, die mit dem Konzept nicht vertraut sind, müssen es erst erlernen.
  • Erfordert sorgfältiges Management von Lebenzyklen und Gültigkeitsbereich der Objekte.

Verwandte Patterns

  • Factory-Methoden und Abstract Factory: Werden zur Erzeugung von Instanzen genutzt, die per DI injiziert werden.
  • Service Locator: Eine Alternative zu DI, um Dienste oder Komponenten zu finden, entkoppelt den Prozess aber nicht so effektiv.
  • Singleton: Häufig Ergänzung zu DI, um eine einzige Instanz zu liefern. eines Service für die gesamte Anwendung zu liefern.

Quellen