/ Architektur Widerspricht dem "klassischen" Ansatz "jeder besorgt sich seine Sachen selbst" Das Objekt, bzw. die Klasse gibt die Steuerung der Abhängigkeiten aus der Hand Sog. Hollywood-Prinzip: "Don't call us, we call you"
Objekten Verwendet ein erweitertes Factory Entwurfsmuster als Basis Ist eine Anwendung des IoC Paradigmas Die Anwendung des Musters auf bestehenden Code ist ein Refactoring Prozess Es gibt Bibliotheken in PHP, die am Ende des Prozesses stehen
Erzeugen von kritischen Objekten Der Klassenname der Abhängigkeit ist fest in der instanzierenden Klasse "verdrahtet" Selbst beim Auslagern des Klassennamens der Abhängigkeit kümmert sich dennoch die Klasse selbst um die Bereitstellung der Instanz
Referenzierung oder Verwendung einer konkreten Implementierung in einer Klasse. class FooImpl { public function __construct() { $oVar = new BarImpl(); } } class FooImpl { public function __construct(BarImpl $oParam) { // ... } }
über den Konstruktor beim Erstellen der Instanz übergeben und in der Instanz vorgehalten und / oder weiter durchgereicht. Getter / Setter Injection Instanzen werden per setFoo(FooInterface $oFoo) und getFoo() gesetzt und geholt. Man greift nicht mehr auf die Eigenschaft direkt zu, da auch die Beschaffung der Instanz verborgen wird.
ersten Zustand einer Instanz beschreiben. Schlecht: public function __construct() { $this->oDb = new DbConnImpl( "localhost", "user", "pass"); } Besser: public function __construct(DbConnImpl $oDb) { $this->oDb = $oDb; }
stehen. Dieser Schritt löst die Abhängigkeit zu einer konkreten Implementierung. statt: public function setDbConn(MySQLDbConn $oConn) {} lieber: public function setDbConn(Queryable $oConn) {} => Vorteil: Theoretisch kann die DB nun auch eine SQLite sein, solang das Interface "Queryable" erfüllt ist.
Variablen, als auch Singletons in Konstruktoren und Methoden gemeint! denn: public function __construct() { $this->oVar = DbConn::getInstance(); } ist das Gleiche wie: public function __construct() { $this->oVar = $GLOBALS['dbconn']; } Es gibt jedoch Ausnahmen, bei denen es Sinn macht einen Singleton einzusetzen!
DbConn) Weiterverteilung der Objekte bei der Initialisierung des Frameworks z. B. MVC-Framework 1. Bootstrap erzeugt DbConn 2. Bootstrap erzeugt MVC-Router 3. Bootstrap übergibt DbConn an MVC Router 4. MVC Router findet passenden Controller 5. MVC Router übergibt DbConn an Controller 6. Controller erzeugt Service Layer 7. Controller übergibt DbConn an Service Layer => DbConn ist nur ein Mal erzeugt worden!
Sie erzeugen Instanzen der geforderten Klasse Sie "konfigurieren" die neue Instanz mit den bekannten Abhängigkeiten Manche können Abhängigkeitsgraphen auflösen => Klasse A braucht eine Instanz von B => B braucht im Konstruktor eine Instanz von C Meist erkennen diese dann auch "Circular References" => Wenn C im o. g. Beispiel eine Instanz von A benötigen würde
konfiguriert. Hierbei wird die Implementierung für ein Interface angegeben. $oCont = Container::getInstance() $oCont->useDep('Queryable', 'MySqlQueryableImpl'); $oCont->manageClass('Foo', 'aNickName'); $oFoo = $oCont->get('aNickName'); assert (($oFoo instanceof Foo) === true) && (($oFoo->getConn() instanceof Queryable) === true) Ein assert auf MySqlQueryableImpl würde ebenfalls funktionieren, aber gegen das Prinzip verstoßen.
neu. Eine Klasse wird per DocBlock annotiert. class Foo { /** * @inject */ public function __construct(Queryable $oConn){ } } $oCont = Container::getInstance(); $oFoo = $oCont->get('Foo');
Beispiel aus einer FLOW3 YAML Konfiguration: F3\MyPackage\Foo: properties: bar: { object: F3\MyPacka ge\BarInterface } $oFoo = Container::getInstance()->get('Foo')