我正试图找出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);
答案 0 :(得分:1)
如果是这样,那么最好的方法就是倒退工作......
是。正如我在评论中提到的,您首先设置最内层的对象。
如果一个对象在内部创建了另一个未公开的对象,那么它可以在适当的情况下传递其注入的对象。例如:
class DoSomething {
// ...
public function foo() {
$foo = new Foo();
$foo->setLogger($this->_logger);
return $foo->bar();
}
}
但是,如果该秘密Foo
对象需要引用DoSomething
没有的其他内容,那么您就会遇到设计问题。如果发生这种情况,你需要做任何适当的事情:
foo
之前,将foo()
对象注入父对象。foo()
之前将该依赖项注入父对象。答案 1 :(得分:0)
您只需要在直接需要它们的类中包含依赖项。由于每当基类加载时都会加载所需/包含的文件,因此它们将自动可用于任何子类。