聚合根的子节点如何使用来自另一个聚合根

时间:2016-02-03 21:50:32

标签: domain-driven-design cqrs event-sourcing aggregateroot

例如,考虑具有多个菜单的商店。菜单列表项和一个项可以列在多个菜单中。

想象一下菜单聚合根和项聚合根。菜单会有一个MenuItem的集合,它引用一个Item AR以及特定菜单中的订购信息。

我的问题是,您如何从MenuItem访问Item的名称,价格和描述。比方说,例如,菜单AR处理命令按价格重新排序(我知道听起来与UI有关,但我在这里严格说话域模型,idk也许这是一个商业规则,菜单必须在一个菜单中排序特别的方式?)

您是否会在MenuItem中获取Item AR的值对象?如果是这样,Menu AR是否会保留对域服务的引用以查找Item的值对象,或者MenuItem是否使用域服务。

我猜,菜单AR应始终保持一致,这可能意味着当一个项目添加到菜单时,MenuItem会保存对该项目的值对象的引用。

这听起来会破坏“按身份引用实体”规则,因此MenuItem将保留对ItemId的引用。考虑到事件源的使用,无论何时您想要将命令应用于菜单AR,它都会重放所有事件,使其保持一致,然后发出命令重新排序菜单项。

MenuItem只有ItemId,而不是该项目的详细信息,这是加载这些项目的时间吗?菜单可以遍历它的MenuItems,然后使用服务通过ItemId为每个MenuItem查找Item值对象,然后执行排序。

感谢您的任何意见,非常感谢。

1 个答案:

答案 0 :(得分:3)

就像你说的那样,这应该在查询方面完成。我不确定我是否看到如何保持域中的排序一致有用?如果菜单有不同的订购策略,也许我会这样做,但即便如此。总之...

如果AR使用的数据不在其边界内,那么它只能最终保持一致,除非您每次交易修改多个AR,这通常是一种不好的做法。

您可以这样做:

menu = menuRepository.findById(menuId);
menu.reorder(itemPricingService);

有些人还喜欢在应用服务/命令处理程序中解析依赖关系:

menu = menuRepository.findById(menuId);
itemIdList = menu.items().map(extractItemId);
itemPriceList = itemPricingService.pricesOf(itemIdList);
menu.reorder(itemPriceList);

但是,您还需要收听ItemPriceChanged等事件,以使菜单顺序与价格变化保持一致。

还有另一种策略,您可以将定价信息复制到MenuItem。价格将最终保持一致,依赖于事件,并且价格发生变化的项目将重新订购。

您可以使用与实施here类似的重新排序策略。请查看reorderFromProduct的{​​{1}}实施。