【问题标题】:Parent/Child relationship - should I store reference to parent in child?父/子关系 - 我应该在孩子中存储对父母的引用吗?
【发布时间】:2014-09-04 09:56:08
【问题描述】:

我有两节课。一对多关系中的父母和孩子。 Parent 有一个名为 $children 的数组,其中存储了 Child 实例。 Child 有一个私有的 $name 属性和公共的 getter/setter 方法。我想要名字独特的孩子。

我解决这个问题的方法是,我将 Parent 实例传递给 Child 的构造方法,我将它存储在 $_my_parent 中,然后在 Child 的 setName($name) 方法上,我要求 Parent 实例循环所有子实例并检查是否可以使用 $name。

非常简单。

Q1:这显然会产生无限递归。那是问题吗?什么时候序列化?

Q2:还有其他方法吗?

【问题讨论】:

    标签: php oop relationship


    【解决方案1】:

    虽然以这种方式 100% 保证数据完整性在理论上可能很好,但实际上无论如何都无法实现。您始终可以在对象上设置属性,使其不唯一,例如使用 Reflection API。

    我会保持简单:

    • 您的子对象是哑数据对象,它们对父对象一无所知并且是自包含的
    • 父级只是持有子对象,它不会将自己注入其中
    • 在父对象另一个外部类中,都有一个验证方法,通过迭代子对象并确保它们的唯一性来检查父子组合是否有效

    只需在必要时显式调用此验证方法,不要在修改子项时自动触发它。它消除了很多复杂性和问题,而且缺点很少。

    【讨论】:

    • 所以你的关键点是我不应该对我的 Child 对象的 setter 方法进行任何检查(使它们变得愚蠢),并且我应该在 Parent 或某些上实现并显式调用验证方法设置名称之前的工厂类。我确实同意,从逻辑上讲,对 Child 的 setter 方法进行验证是没有意义的,因为它涉及其他孩子,因此它应该是 Parent 的任务。我不太确定我是否同意将验证从 Child 的 setter 移到其他地方可以消除复杂性(我实际上认为它会增加它)。为什么这么说?
    • 更简单,因为显然每个对象本身都更简单,职责也更明确。尤其是孩子知道他们的父容器是很奇怪的。或者,您可能会将子级视为父级的无关实现细节,并且只允许通过父级的方法修改父级的内容。可能只返回不可变的子代或从父代克隆的子代,因此它们也不能通过引用来修改。
    • '特别是孩子知道他们的父容器是很奇怪的......' - Doctrine 实体不这样做吗?
    • 不知道,没用过。
    • 那么也许您想将您的 API 设计为$family->setNameOfChild(1, 'Tom')。为避免返回子时通过引用间接修改,请使用public function getChild($num) { return clone $this->children[$num]; }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-13
    • 1970-01-01
    相关资源
    最近更新 更多