这是我的示范案例:
[EEEE, CCC1]
我希望在OrderPosition中有一个指向“父级” /拥有的Order项目的指针;但是,由于Order被视为汇总根,因此我希望Order负责创建OrderPositions的集合。
当最终订单尚未创建时,应如何在每个OrderPosition中放置Order项目? 我目前的方法是将其延迟设置在Order的ctor中,但是严格来说,这会使OrderPosition发生变化。
答案 0 :(得分:1)
您在这里有几个冲突的设计决策:
正如您所说,当前的实现方式允许(OrderPosition
在以后添加额外的引用,从而损害了(1)。
如果卸下(2),可以使问题消失。在什么情况下,您将引用OrderPosition
并想导航到它所属的Order
?是否可以将这种情况重新定义为Order
的责任,从而删除循环引用?
您可以更改(3),以使构造函数使用信息来创建OrderPositions
,而不是OrderPositions
本身。在您的示例中,这是微不足道的,但是如果实际上您有多个不同的工厂供入一个构造函数,则可能会变得混乱。
或者,如果您放松(4),则可以将部分构造的对象传递到OrderPosition
构造函数/工厂中:
public static function fromArray($orderData)
{
assert(isset($orderData['orderId']));
assert(isset($orderData['positions']));
$instance = new self($orderData['orderId']);
foreach ( $orderData['positions'] as $positionData ) {
$instance->orderPositions[] = OrderPosition::fromArray($positionData, $instance);
}
return $instance;
}
虽然它看起来仍然像是突变,但它与您在任何构造函数中所做的突变相同-您正在创建对象的初始状态。
在支持重载或命名构造函数的语言中,fromArray
将成为构造函数,并且可能不会与其他构造函数共享任何实现。在PHP中,您可以使用空的private function __construct(){}
和以$instance = new self;
开头的静态方法来模拟该模式