子类的PHP依赖注入

时间:2011-11-22 00:17:37

标签: php dependency-injection

我正试图找出PHP中依赖注入的最佳实践。

问题:我是否必须将子类的所有依赖项注入父类?我根据构图关系使用术语“父母”和“孩子”。

我犹豫是因为我发现自己给了父类各种依赖关系,以便它可以将它们传递给依赖的子类。

编辑:

以下是我所谈论的更具体的例子。 MyClassA不需要数据库连接对象或记录器。但是,DoSomething确实需要这些对象。将数据库连接和记录器连接到DoSomething实例的最佳方法是什么?我不想为了单元测试而使用单例对象或全局对象。此外,此示例仅用于类。如果有3个或4个,第3个或第4个需要某个对象实例但前2个或3个不需要怎么办? MyClassA只是将对象传递给下一个,依此类推吗?

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;
  }
}

下面展示的示例是最好的方式吗?如果是这样,那么最好的方法就是倒退,可以这么说......?

    $logger = new Logger();
    $db = new DBConnection();    

    $doSomething = new DoSomething();
    $doSomething->setLogger($logger);
    $doSomething->setDBConnection($db);

    $a = new MyClassA();
    $a->setDoSomething($doSomething);

2 个答案:

答案 0 :(得分:1)

  

如果是这样,那么最好的方法就是倒退工作......

是。正如我在评论中提到的,您首先设置最内层的对象。

如果一个对象在内部创建了另一个未公开的对象,那么它可以在适当的情况下传递其注入的对象。例如:

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

但是,如果该秘密Foo对象需要引用DoSomething没有的其他内容,那么您就会遇到设计问题。如果发生这种情况,你需要做任何适当的事情:

  • 在调用foo之前,将foo()对象注入父对象。
  • 在调用foo()之前将该依赖项注入父对象。
  • 将依赖项添加为函数参数。
  • 将代码重构为更好的设计,不会产生该问题。

答案 1 :(得分:0)

您只需要在直接需要它们的类中包含依赖项。由于每当基类加载时都会加载所需/包含的文件,因此它们将自动可用于任何子类。