2017-03-17 44 views
0

我希望我管理一个comprehensiv的方式来解释这一点: 假设我们有一个“库”对象。在这个“库”中,我们有许多“书”对象,每个“书”对象都有一个“作者”对象。 事情是这样的:Dependencie注射斗争

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方法注入“作者”,使其可选的,但我想用一个工厂打造“书”的对象。

那么,到底是什么要告诉你的工厂(或仓库)什么可选依赖它应该建立对象的最佳方式?

也许在这里我的做法是完全错误的,和我的问题并没有做出很大的意义。如果是这样,我表示歉意。 任何帮助让我在正确的方向将不胜感激。

+0

尝试找到一个关于'延迟加载对象和依赖注入'的好文章,这样''dependencys'只会在真正需要的时候创建。 – JustOnUnderMillions

+0

谢谢。这帮了我很多。然而,我有点惊讶;当进行惰性加载和依赖注入时,没有很多结果。这不是每个人都应该感兴趣的话题吗?或者这是很常见的做法,我的缺乏理解是责备? – minychillo

回答

0

使用懒惰的生活方式为您的author依赖项。您可以注入authorFactory,而不是将author对象注入到book构造函数中。 authorFactory创建便宜,并能够按需创建author对象。您可能还需要为book构造函数添加一个authorId,以便在必要时知道要创建哪个作者。然后,如果/当你book对象需要使用它author属性,它确实

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

你也可以做到这一点使用闭包,而不是一个类工厂。

在你的榜样,我假设你正在做的事情一样显示与作者的名字沿着一个书单,然后你看作者的全部细节,如果用户点击书的作者。所以在这种情况下,大概只需要作者的姓名,在这种情况下,您可以将作者的名称设置为book的属性,而且创建起来很便宜。然后,如果用户点击该书的作者,则执行延迟加载。

这种方法的另一个好处是,你可能需要进行某种形式的作者缓存这样你就不会每次都打你的数据库,如果同一作者被点击多次。你可以在你的authorFactory里做这个缓存,并使之对book不可见。

+0

非常感谢!注入工厂类到懒惰加载....当然! – minychillo

+0

两个迷你后续问题: 1)您会推荐什么?关闭还是工厂注入?有什么区别吗? 2)那么“$ this-> authorFactory.createAuthor($ this-> authorId)”呢?我从来没有看过这个符号。这是一个错字还是有效的语法? – minychillo

+0

1)就个人而言,我会使用一个工厂,因为我认为如果您有一个定义良好的工厂对象,其唯一目的是创建Author对象,那么使单元测试更容易。我认为在编写单元测试时,闭包使得它更容易混淆。但这只是我的偏好,这可能是因为工厂就是我习惯的。 2)是的,这是一个错字。我主要是C#程序员,所以不小心使用了这种语法。 –