號學說2曲目協會通過持有端,當它試圖對你的實體的行爲的影響最小,但不希望添加這種功能。
跟蹤反面變化的標準方法是通過在實體上添加邏輯來更新自己的邊,從而確保它們保持同步。
在你的榜樣,你可以有的addChild,removeChild之和的setParent函數做這樣的事情:
public function addChild(Organization $child)
{
$this->children[] = $child;
$child->setParent($this); // < update the owning side
}
public function removeChild(Organization $child)
{
$this->children->removeElement($child);
$child->setParent(null); // < update the owning side
}
public function setParent(Organization $parent = null)
{
$this->parent = $parent;
}
你可以看到,現在有一個新的問題,必須始終使用addChild/removeChild之功能(即在反面進行更改)保持同步(或自己同步,作爲主叫方)。這導致你不得不制定一項政策,要麼呼叫者必須始終更新自己的方面,或反面。
您可能使setParent
功能也更新反側,但是你必須非常小心作爲很容易導致無限遞歸:
public function addChild(Organization $child)
{
$this->children[] = $child;
// safely update the owning side
if ($child->getParent() != $this) {
$child->setParent($this);
}
}
public function removeChild(Organization $child)
{
$this->children->removeElement($child);
// safely update the owning side
if ($child->getParent() == $this) {
$child->setParent(null);
}
}
public function setParent(Organization $parent = null)
{
$oldParent = $this->parent;
$this->parent = $parent;
// update the inverse side
if ($oldParent) {
$oldParent->removeChild($this); // will not call setParent
}
if ($this->parent) {
$this->parent->addChild($this); // will not call setParent
}
}
從增加的複雜性
除此之外,該方案例如,將很多孩子從一個父母移動到另一個父母時不理想,因爲removeChild需要線性時間,從而爲移動創建一個O(n^2)運行時間。