Domain driven design 领域驱动设计:如何对大型但很少有行为的关系建模

Domain driven design 领域驱动设计:如何对大型但很少有行为的关系建模,domain-driven-design,domain-model,Domain Driven Design,Domain Model,假设我有两个实体User和Item。域中这两个实体之间的唯一行为是用户可以喜欢某个项目。由于对用户可以喜欢多少项没有限制,因此这种多对多关系可能很大 我认为让用户在其模型中或以其他方式包含他们喜欢的项目列表是没有意义的,因为我必须加载一个潜在的大型项目集合,以便只添加一个项目。从域设计的角度来看,让任何一个实体在其字段中引用另一个实体对我来说也没有意义,因为任何行为都不需要存在项或用户的集合 我确实需要保持这种关系,因为UI需要显示用户喜欢的项目列表和喜欢项目的用户列表。这个需求可以通过一个读取

假设我有两个实体User和Item。域中这两个实体之间的唯一行为是用户可以喜欢某个项目。由于对用户可以喜欢多少项没有限制,因此这种多对多关系可能很大

我认为让用户在其模型中或以其他方式包含他们喜欢的项目列表是没有意义的,因为我必须加载一个潜在的大型项目集合,以便只添加一个项目。从域设计的角度来看,让任何一个实体在其字段中引用另一个实体对我来说也没有意义,因为任何行为都不需要存在项或用户的集合

我确实需要保持这种关系,因为UI需要显示用户喜欢的项目列表和喜欢项目的用户列表。这个需求可以通过一个读取模型来满足,但我仍然需要一个域概念来捕获这种关系,以便它能够持久化

我能想到的一种方法是引入聚合的关系类型,比如UserLikeItem,并让user.like(item)方法返回UserLikeItem的实例,然后我可以使用UserLikeItemRepository来持久化它


这是一个有效的解决方案吗?DDD中建模这种大型但非行为关系的自然方式是什么?

我将对此进行挖掘:),IMO如果没有行为,它就不存在于“域模型”中,如果您的绝大多数概念没有行为,那么您就不需要“域模型”,您可能应该考虑一种模式,而不是域模型

我想将你的问题解释为“我如何以绩效的方式维持多对多的关系?” 对于这个问题,我们有多个答案,一个是您提到的,另一个可能只是在类中存储id列表

域模型和持久性后端的面向对象表示是两个独立的东西,域模型首先是行为,因此您需要考虑行为,然后将属性添加到域模型中,该行为将影响这些属性,否则您需要的是“持久性后端的面向对象表示”(DTO)


但是,当你有一个领域模型的案例时,它会变得很棘手,但只有几个概念是贫乏的,缺乏行为,但这是另一天的问题:)

“Like”是领域事实,可以用实体来表示。
项目有喜欢->项目包含喜欢的集合。
此集合仅用于添加和删除likes->Item have LikeCount属性,并且likes集合对于存储库查询是可选的(仅在Item.AddLikeFrom(用户)和Item.RemoveLikeFrom(用户)方法中使用)


看起来,这种关系是非行为的,但事实上它是一种关系方的行为。

因为我不久前遇到过这种情况,下面是我的看法。用户和项目是不同聚合的一部分,它们彼此不了解/不关心(即使项目具有用户ID)。“相似系统”(LS)是从什么的不同集合

LS也并不真正关心用户或项目,尽管我看不出用户以外的其他人会喜欢什么,我可以说,喜欢总是意味着一个用户ID(而不是整个用户概念)和一个主题(项目、视频、图片、帖子等)

LS只是保持用户Id和另一个特定类型的itemId的关联(如果您不希望LS与某个项耦合,那么它可以是字符串)。每当用户喜欢某个东西时,就会发出一个命令:RegisterLikeForItem{UserId,ItemId,ItemType}。LS处理程序将存储该信息,然后发布一个事件UserLikedItem。它的一个处理程序将是一个计数器,用于计算有多少用户喜欢该项目。另一个处理程序可以列出一个用户喜欢哪些项目(这将由UI查询)


每个处理程序服务于一个用例,可能每个都有自己的存储。我知道它看起来很复杂,但实际上很简单(一个用例需要一个处理程序,也许还需要一个存储),而且非常灵活,易于维护。该系统可处理一种或1000种项目类型。

我喜欢(双关语!)您的解决方案,尽管它不需要是
用户
IMO上的方法。它还允许您捕获其他信息,例如喜欢项目的时间、在什么环境下等。相同的AR也可以用于,但也许你需要为它找到一个更好的名称。我同意,我唯一可能添加的是一个
LikeCounter
,这样你就可以显示一个项目的总like计数,而不必点击
UseLikeItem
数据源。事务对象或域事件“UserLikedItem”你给了我们这么少的东西,这似乎很合适。我不同意“如果没有行为,它就不存在于“域模型”中”。任何具有域含义/定义域概念的内容都是域的一部分,无论它是行为还是数据结构。