Mittlerweile findet die Dependency Injection – kurz DI – auch in der PHP-Welt immer mehr Verbreitung. Dennoch möchte dieses Entwurfsmuster hier noch einmal vorstellen. Ziel von DI ist es, Abhängigkeiten zwischen Objekten zu minimieren und im Idealfall eine erhöhte Wiederverwendbarkeit von Klassen zu ermöglichen.
Bisher wurden Abhängigkeiten zu anderen Objekten, beispielsweise bei einer Aggregation, von dem “übergeordneten” Objekts aufgelöst. Dazu wiederrum benötigt ein Objekt Kenntnisse über das zu erzeugende Objekt und dessen Implementierung. Folgendes Beispiel soll dies noch ein mal veranschaulichen:
<?php
class Car {
private $engine = null;
public function __construct() {
$this->engine = new Engine();
}
}
Bei der Dependency Injection Entzieht man nun den Objekte die Verantwortung, Abhängigkeiten aufzulösen. Stattdessen erzeugt nun der Entwickler die benötigten Objekte und teilt beispielsweise dem Objekt vom Typ Car mit, welches Objekt vom Typ Engine es nutzen soll:
<?php
$Engine = new Engine();
$Car = new Car($Engine);
Ein Vorteil sollte hier schon erkennbar sein. Es ist nun theoretisch möglich, der Car-Instanz einen anderen Motor zu übergeben. Es müssen nur die gleichen Methoden vorhanden sein. Sollte man, um beim Beispiel zu bleiben, allerdings einen Motor eines Drittanbieters verwenden wollen, wird man nicht um das Schreiben einer Adapter-Klasse herumkommen.
Die Abhängigkeiten können über den Konstruktor, aber auch über Setter oder direkt an eine Objekteigenschaft, injiziert werden. Es gibt eine Faustregel, wann man welche der Möglichkeiten nutzen sollte:
- Constructor Injections für zwingend benötigte Abhängikeiten
- Setter Injections für optionale Abhängikeiten
- Property Injections ebenfalls für Optionale Abhängigkeiten. Besser jedoch Setter verwenden
Eine Erweiterung des Entwurfsmusters sind Frameworks oder auch DI Container wie z.B. Symfony Dependency Injection. In diesen Containern werden alle Abhängigkeiten definiert und anschließend automatisiert aufgebaut. Solche Frameworks sind aber in der Regel nur dann Sinnvoll, wenn man mit vielen unterschiedlichen Objekten mit vielen Abhängigkeiten arbeitet. In den meisten Fällen sollte jedoch eine manuelle Dependency Injection ausreichend sein
.