Domain driven design 聚合根和现有数据(来自数据库)

Domain driven design 聚合根和现有数据(来自数据库),domain-driven-design,Domain Driven Design,我正在努力按书办事,很难理解是否有一种单一的想法 假设我有一辆普通的购物车。当用户浏览商店时,他可以向购物车添加shoppingcartorlines。每个步骤都保存到数据库中。让我们想象一下,无论出于何种原因,用户在每次购物会话中可以花费的最大金额意味着所有shoppingcartorlines的总和不能超过一定的金额 因此,ShoppingCart将成为我的聚合工具。现在,在添加新的ShoppingCardOrderLines时,我首先需要从数据库中提取现有的订单行,创建聚合根,然后在该实例

我正在努力按书办事,很难理解是否有一种单一的想法

假设我有一辆普通的
购物车
。当用户浏览商店时,他可以向购物车添加
shoppingcartorlines
。每个步骤都保存到数据库中。让我们想象一下,无论出于何种原因,用户在每次购物会话中可以花费的最大金额意味着所有
shoppingcartorlines
的总和不能超过一定的金额

因此,
ShoppingCart
将成为我的聚合工具。现在,在添加新的
ShoppingCardOrderLines
时,我首先需要从数据库中提取现有的订单行,创建聚合根,然后在该实例上调用
AR.AddItemToCart(Item)

从DDD的角度来看,这个流程应该如何实现? 我是否应该让存储库拉取给定购物车的所有
shoppingcartorlines
,并使用相同的
AR.AddItemToCart(Item)
方法将它们添加到AT实例中(这在某些域服务中完成)?或者我的存储库应该直接返回包含DB中所有数据的AR吗?还是第三条路?可能有专门的构造函数,其中一个参数是
项的集合
已保存在数据库中

我想找到一些一致的方法来解决这个问题,因为如果我最终在读取端读取整个聚合根,可能会很快变得非常大/复杂。另外,从我在几个地方读到的内容来看,强制规则(AR.AddItemToCart(Item)中的规则)应该只在写端执行,这意味着从DB读取时应该以其他方式执行

从DDD的角度来看,这个流程应该如何实现

通常的模式遵循中的描述:存储库提供根目录的实例

这里的部分要点是,无论是应用程序还是域模型,都对如何存储聚合的细节没有任何兴趣或投资——存储库将其他组件与数据的持久表示是否是RDBMS中的行、文档存储中的文档的知识隔离开来,或者只是磁盘上的字节

这通常意味着存储库需要类似于构建器/工厂(由域模型实现)的东西,以便它可以将持久化表示转换为(当前)域模型的内存表示


若我们假设域模型并没有setter,那个么这是否意味着存储库实际上通过通常的域接口(方法)来设置实例,这实际上意味着在读取端再次强制执行所有规则

这里有一件重要的事情需要认识到:阅读方根本不应该强制执行任何规则。这就是写作模型的工作

但是:如果需要将域不可知字节转换为域模型值,或者将未验证的值对象转换为已验证的值对象;这些转换的逻辑由域模型提供

从DDD的角度来看,这个流程应该如何实现

通常的模式遵循中的描述:存储库提供根目录的实例

这里的部分要点是,无论是应用程序还是域模型,都对如何存储聚合的细节没有任何兴趣或投资——存储库将其他组件与数据的持久表示是否是RDBMS中的行、文档存储中的文档的知识隔离开来,或者只是磁盘上的字节

这通常意味着存储库需要类似于构建器/工厂(由域模型实现)的东西,以便它可以将持久化表示转换为(当前)域模型的内存表示


若我们假设域模型并没有setter,那个么这是否意味着存储库实际上通过通常的域接口(方法)来设置实例,这实际上意味着在读取端再次强制执行所有规则

这里有一件重要的事情需要认识到:阅读方根本不应该强制执行任何规则。这就是写作模型的工作


但是:如果需要将域不可知字节转换为域模型值,或者将未验证的值对象转换为已验证的值对象;这些转换的逻辑是由域模型提供的。

DDD对此没有规定。它更多地取决于您的环境、约束和自己的偏好

我是否应该让仓库为给定的客户提取所有购物卡通线 购物车,并将它们添加到AT实例中,循环相同 AR.AddItemToCart(Item)方法(在某些域中执行此操作 服务)?或者我的存储库是否应该返回AR,其中包含来自的所有数据 DB直接

  • 前者是您在事件源场景中要做的事情。你 根据相同的聚合转换函数重播所有事件 前向应用程序将使用并以 最新加载的聚合

  • 后者是一个更传统的以国家为基础的国家所发生的情况 持久性就像RDBMS。在这里,骨料再水化通常进行 通过一条完全不同于面向前方的域操作的路径 因为你一次加载所有东西,基本上绕过了域。没有连续的小变换必须检查不变量。 存储库应该能够自主地查询数据库,并将数据转换为完整的聚合。在保留实体封装的同时,有不同的技术可以实现这一点——允许持久层访问一个保护级别,该级别允许持久层修改通常仅对域可用的字段,创建实体可以“吸收”的中间数据对象,等等


DDD在这方面相对没有规定性。它更多地取决于您的环境、约束和自己的偏好

我是否应该让仓库为给定的客户提取所有购物卡通线 购物车和添加