代码之家  ›  专栏  ›  技术社区  ›  Community wiki

在OOP中,依赖项是否应该包含对其父项的引用?

  •  1
  • Community wiki  · 技术社区  · 8 月前

    我有一个订单对象来表示预期订单/收据。这是一个实体。它有一个身份。

    我有一个Writer对象来读取Order对象的属性并很好地显示它。

    为客户的所有账单详细信息设置单独的getter有点麻烦。

    因此,我正在考虑让Writer对象从Order对象中获取Client的Billing Details Value对象。(我想客户的计费详细信息值对象被称为“依赖项”——如果我错了,请纠正我)

    现在,如果我这样做,我希望这个依赖项“知道”原始持久数据是否发生了更改

    即,如果countryId从“214”更改为“35”

    这样depency就可以返回新的countryAsPrettyString“Mexico”,而不是“Ecuador”的旧值。

    所以我想我会在Order对象中有一个工厂方法,并且可以将Order对象注入到Client的Billing Details Value对象的构造函数中,这样Billing Details对象总是从Order的原始持久数据属性中派生它的属性。

    您对此行动计划的反应是:

    A: 天哪,很明显,这几乎是唯一的方法

    B: 天哪!几个月后,为一些严重的头痛留出一些时间——你会产生一堆混乱的联想——我很同情你。

    或 C: [其他]


    我之所以这么问,是因为这对我来说似乎是一种双向关联。

    订单 计费详细信息对象

    计费详细信息对象 订单

    我读到双向关联是糟糕的OOP实践。

    4 回复  |  直到 3 年前
        1
  •  0
  •   Scott Saunders    13 年前

    我建议您创建一个Address类。如果您需要BillingAddress和ShippingAddress这两个属性,则Order对象可以具有这两个特性。您有一个Writer类来创建订单的视图。创建AddressWriter类以创建Address对象的视图。然后你可以这样做:

    public function printOrder($order)
    {
        // print order stuff here...
    
        $addressWriter = new AddressWriter();
    
        echo "<h1>Billing Address</h1>";
        $addressWriter->printAddress($order->getBillingAddress);
    
        echo "<h1>Shipping Address</h1>";
        $addressWriter->printAddress($order->getShippingAddress);
    
        // print more order stuff ...
    }
    
        2
  •  0
  •   FrantiÅ¡ek Žiačik    13 年前

    不确定我是否确切知道你在问什么,但这可能会有所帮助:

    Change bidirectional association to unidirectional

    这个:

    Change unidirectional association to bidirectional

        3
  •  0
  •   Mark Nold    13 年前

    所有这一切都是因为“为客户的所有账单详细信息设置单独的getter有点麻烦。”。

    我不知道你的类到底是如何实现的,但有可能使用PHP的 __call 自动构建那些getter?

    如果你设置了一个约定,getBillingWhatever-inOrder将返回$billing,该怎么办;getWhatever()并实现__call来提供此功能?

        4
  •  0
  •   Extrakun    13 年前

    让子类保持对父类的引用会加强耦合。如果必须这样做,我建议您将父级设置为接口,并让子级引用该接口。或者,您可以尝试通过关联数组或数据容器将相关信息传递给子类。