当PHP对象方法创建一个新对象时,最好将其保存为对象属性


When a PHP object method creates a new object, is it best to save it as an object property?

假设我在PHP中有两个类,一个图书类和一个作者类。假设我要创建一个新书对象。

// $book is now a book class
$book = new book('War and Peace');

现在让我们说我想要那本书的作者。为此,我的对象设置要求我从书中获取author类。

// gets an author class chained with a method to get it's name
$author = $book->getAuthor()->getName();

在$book->getAuthor()调用中,是否最好将author对象"保存"到book中的属性中?

public function getAuthor()
{
    if(is_null($this->author_object)) {
        $this->author_object = new author($this->author_name);
    }
    return $this->author_object;
}

这个例子可能不是最好的,但我希望它能很好地代表我的问题。此外,我已经知道数据库查找对性能有很大影响,所以现在不需要这样做。

基本上,我的问题是,如果需要的话,再次创建author对象,或者将author对象保存为一个属性,这样就不需要再次创建了。

是的,如果您可能重复使用Author数据,最好将Author对象保存为Book对象的属性。然而,如果实例化另一个拥有相同作者的Book对象,并使用新书的对象将对该作者的更改持久化到DB中,则需要担心会发生什么。然后,您的原始图书将有一个过时的Author对象,该对象的数据不一致。

Propel ORM使用相关对象的全局实例池来简化此过程。(尽管如此,我不确定它是否真的在上述情况下保持了一致性,因为我似乎记得遇到过与此有关的错误,但它至少可以防止数据库查询获取已经看到的对象。)无论如何,Propel是一个很好的ORM,与您使用的相关对象和字段的语法完全相同,所以您可能需要考虑使用它。

一般来说,很难想象这样一种情况,即Author不是存储在Book类中的,而Book不是AuthorBooks属性的成员。对他们来说,"延迟加载"是可以的,这就是您的示例所做的,但加载后,您希望通过重复调用引用同一对象,而不仅仅是相同的数据。

但在某些情况下可能不会发生这种情况,但我会对您选择像基本访问器一样命名方法表示异议:-)