Dependencie注射斗争

时间:2017-03-17 16:20:59

标签: php dependency-injection

我希望我能以理解的方式解释这个问题: 让我们说我们有一个“库”对象。在这个“库”中,我们有许多“书”对象,每个“书”对象都有一个“作者”对象。 像这样:

class library {

  private $books = [];

  public function addBook( book $book){
    $this->books[]=$book;  
  }

  function getAllBookTitles(){
    foreach($this->books as $book)
      $r[] = $book->getTitle();
    return $r;
  }

}


class book {

  private $author;
  private $title;

  public function __construct( author $author ){
    $this->author = $author;
  }

  function getTitle(){
    return $this->title;
  }

  function setTitle( $title ){
    $this->title = $title;
  }

}


class author {

  public function __construct(){}

}

现在我真的不明白: 在某些视图中,当我只需要一个库的所有书名列表时,为什么还要构建作者对象呢? 这只是一个例子,但是“作者”对象的图像构建起来相当昂贵......这将为不需要的数据使用大量资源。

我知道您可以通过setter方法注入“author”以使其成为可选项,但我想使用工厂来构建“book”对象。

所以最后,告诉你的工厂(或存储库)应该构建对象的可选依赖项的最佳方法是什么?

也许我的方法完全错了,我的问题没有多大意义。如果是的话,我道歉。 任何有助于我朝着正确方向前进的帮助都会非常感激。

1 个答案:

答案 0 :(得分:0)

author依赖项使用懒惰生活方式。您没有将author对象注入book构造函数,而是注入authorFactoryauthorFactory创建起来很便宜,并且可以根据需要创建author个对象。您可能还需要向authorId构造函数添加book,以便您知道在必要时创建哪个作者。然后,当/ book对象需要使用其author属性时,它会

if ($this->author == null)
{
   $this->author = $this->authorFactory->createAuthor($this->authorId)
}
// Do the rest of your method

您也可以使用闭包而不是类工厂来完成此操作。

在您的示例中,我假设您正在执行诸如显示书籍列表以及作者姓名之类的内容,然后您会显示作者的全部详细信息,如果用户点击该书的作者。因此,在这种情况下,您可能大多数时间只需要作者的姓名,在这种情况下,您可以将作者的名称设为book的属性,并且这样便宜创造。然后,如果用户点击图书的作者,则执行延迟加载。

此方法的另一个优点是您可能希望执行某种作者缓存,因此如果多次单击同一作者,则每次都不会访问您的数据库。您可以在authorFactory内进行缓存,并将其隐藏到book