PHP-Abhängigkeitsinjektion für Kinderklassen

  • Ich versuche, die besten Vorgehensweisen für die Abhängigkeitsinjektion in PHP herauszufinden.

    Frage: Muss ich alle Abhängigkeiten einer Unterklasse einfügen in die übergeordnete Klasse? Ich benutze die Begriffe "Eltern" und "Kind" im Hinblick auf eine Kompositionsbeziehung.

    Mein Zögern ist, dass ich der Elternklasse alle möglichen Abhängigkeiten gebe, so dass dies möglich ist Übergeben Sie sie einfach an abhängige Kinderklassen.

    Bearbeiten:

    Nachfolgend ein konkreteres Beispiel für das, worüber ich spreche . MyClassA benötigt weder das Datenbankverbindungsobjekt noch den Logger. DoSomething benötigt diese Objekte jedoch. Was ist der beste Weg, um die Datenbankverbindung und den Logger zur Instanz DoSomething zu bekommen? Ich möchte keine Einzelobjekte oder globale Objekte für Unit-Tests verwenden. Außerdem werden in diesem Beispiel nur Klassen verwendet. Was ist, wenn es 3 oder 4 gibt und die 3. oder 4. etwas Objektinstanz benötigt, aber die ersten 2 oder 3 nicht? Übergibt MyClassA das Objekt einfach an das nächste usw.

     class MyClassA {
      protected $_doSomethingObject;
    
      public function doSomething()
      {
        return $this->_doSomethingObject()->doSomethingElse();
      }
    
      public function setDoSomethingObject($doSomethingObject)
      {
        $this->_doSomethingObject = $doSomethingObject;
      }
    }
    
    class DoSomething {
      protected $_logger;
      protected $_db;
    
      public function doSomethingElse()
      {
         $this->_logger->info('Doing Something');
         $result = $this->_db->getSomeDataById();
         return $results;
      }
    
      public function setLogger($logger)
      {
         $this->_logger = $logger;
      }
    
      public function setDBConection($db)
      {
         $this->_db = $db;
      }
    }
     

    Ist der beste Weg der Beispiel, das ich unten zeige? Wenn ja, ist der beste Weg, sozusagen rückwärts zu arbeiten ...

         $logger = new Logger();
        $db = new DBConnection();    
    
        $doSomething = new DoSomething();
        $doSomething->setLogger($logger);
        $doSomething->setDBConnection($db);
    
        $a = new MyClassA();
        $a->setDoSomething($doSomething);
     
    22 November 2011
    orourkedd
2 answers
  • Wenn dies der Fall ist, ist die beste Möglichkeit, sozusagen rückwärts zu arbeiten ...

    Ja. Wie ich in dem Kommentar erwähnt habe, richten Sie zuerst die innersten Objekte ein.

    Wenn ein Objekt intern ein anderes Objekt erstellt, das nicht exponiert ist, kann es gegebenenfalls an den injizierten Objekten weitergegeben werden. Zum Beispiel:

     class DoSomething {
    // ...
      public function foo() {
        $foo = new Foo();
        $foo->setLogger($this->_logger);
        return $foo->bar();
      }
    }
     

    Wenn jedoch dieses geheime Foo -Objekt Verweise auf andere Dinge benötigt, die DoSomething nicht, dann haben Sie Designprobleme. In diesem Fall müssen Sie das tun, was angemessen ist:

    • Fügen Sie ein foo -Objekt in das übergeordnete Objekt ein, bevor Sie foo().
    • Fügen Sie diese Abhängigkeit in das übergeordnete Objekt ein, bevor Sie foo() aufrufen.
    • Fügen Sie die Abhängigkeit als Funktionsargument hinzu.
    • Refactor Code in ein besseres Design, das dieses Problem nicht verursacht.
    22 November 2011
    Matthew
  • Sie müssen nur die Abhängigkeiten in die Klassen einbeziehen, die diese direkt benötigen. Da die erforderlichen / enthaltenen Dateien immer geladen werden, wenn die Basisklasse geladen wird, stehen sie automatisch allen untergeordneten Klassen zur Verfügung.

    22 November 2011
    Shane Fright