Domain driven design 聚合根的子级如何使用另一个聚合根的值 例如,考虑一个有多个菜单的商店。菜单列出项目,一个项目可以在多个菜单中列出

Domain driven design 聚合根的子级如何使用另一个聚合根的值 例如,考虑一个有多个菜单的商店。菜单列出项目,一个项目可以在多个菜单中列出,domain-driven-design,cqrs,event-sourcing,aggregateroot,Domain Driven Design,Cqrs,Event Sourcing,Aggregateroot,想象菜单聚合根和项目聚合根。菜单将包含一组菜单项,这些菜单项引用一个项目AR以及特定菜单中的订购信息 我的问题是,您如何从菜单项中访问商品的名称、价格和描述。比如说,菜单AR处理一个按价格重新排序的命令(我知道这听起来与UI有关,但我这里严格说的是域模型,idk可能是一个商业规则,菜单必须以特定的方式排序?) 是否在菜单项中获取项目AR的值对象?如果是这样的话,菜单AR是否会保存对域服务的引用以查找该项的值对象,或者菜单项是否会使用域服务 我想,菜单AR应该始终保持一致,这可能意味着当一个项添加

想象菜单聚合根和项目聚合根。菜单将包含一组菜单项,这些菜单项引用一个项目AR以及特定菜单中的订购信息

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

是否在菜单项中获取项目AR的值对象?如果是这样的话,菜单AR是否会保存对域服务的引用以查找该项的值对象,或者菜单项是否会使用域服务

我想,菜单AR应该始终保持一致,这可能意味着当一个项添加到菜单中时,菜单项包含对该项的值对象的引用

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

MenuItem将只有一个ItemId,而没有该项的详细信息,这是加载这些项的时间吗?菜单可以在其菜单项上循环,然后使用服务按每个菜单项的ItemId查找Item value对象,然后执行排序


非常感谢您的意见,非常感谢

正如您所说,这可能应该在查询端完成。我不确定我是否明白在域中保持顺序一致会有什么用处?如果菜单有不同的排序策略,也许我会这样做,但即便如此。无论如何

如果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
之类的事件

还有另一种策略,您可以将超额定价信息复制到
菜单项中。价格最终将根据事件保持一致,并且价格发生变化的项目将进行重新订购


您可以使用与所实现的类似的重新排序策略。请看一下
reorderFrom
实现的
Product
ProductBacklogItem

感谢您坚持将重新排序作为一项业务规则,这只是我想到的第一件事。这很有帮助,我认为你是对的,
MenuItem
将价格复制到自己身上是有意义的,如果商品的定价在商业术语中对菜单很重要。它只需要像您所说的那样最终保持一致,依靠
ItemPriceChanged
事件保持最新。我必须做更多的研究,因为如果
菜单
AR听了
项目价格变化
所有
菜单项
的事件,那听起来已经错了,在重播
项目时可能会引起副作用