【问题标题】:Turning a CosmosDb Document into a DDD Aggregate将 CosmosDb 文档转换为 DDD 聚合
【发布时间】:2020-07-01 00:40:33
【问题描述】:

我有一个 CosmosDB 文档,它为我的问题空间中的某些东西建模——一辆汽车用于我们的目的。它目前有一堆与模型、颜色、制造年份等相关的属性。我想将 Car 视为 DDD 聚合,包括用于改变对象状态的公共方法以及将方法调用委托给引用的其他对象直接由聚合(在同一文档中)。我知道,在更好的 DDD 实现中,我将拥有与域模型不同的数据模型,并在它们之间具有映射函数,但将文档视为完整的聚合已经足够难了。团队的首选方向是以贫乏的方式处理文档,聚合方法出现在应用程序服务中,这使得聚合逻辑的测试更加困难。直接在文档中包含聚合逻辑有什么缺点吗?

【问题讨论】:

  • 将聚合方法放在实体实例(映射到数据库)本身中非常普遍。事实上,即使在 DDD 文献中的示例中,我也不记得有任何例外。此外,在我的项目中,我自己也做得很好。如果按照 DDD 的建议去做,没有明显的缺点。

标签: domain-driven-design azure-cosmosdb


【解决方案1】:

在 Cosmos DB 中的域数据文档中存储聚合或使用物化视图非常普遍,因为它减少或消除了对频繁运行但通常代价高昂的查询的需求。

例如,在一个简单的电子商务场景中,将订单总额放在订单标题中并通过点读取ReadItemAsync() 获取比执行查询来获取和汇总所有订单项更有效。另一种情况是您需要保留当天所有类别的销售总额。在这种情况下,您有一个文档,其中包含当天的任何销售类别。当每个订单发生时,购物车中每个项目的插入操作都会触发 Change Feed,它会在聚合文档上读取一个点并插入类别总数,将其增加新售出的项目。然后,您无需查询当天的所有销售额(随着订单的增长而变得越来越昂贵),您只需发出一个读点来获取总计,这将是一个 1 RU 的操作。

【讨论】:

  • 我现在看到的唯一麻烦的问题是悬挂在聚合/实体上的公共属性。这些都可以只读并在构造函数中设置吗?这将防止任何人破坏已建立的域逻辑。不确定 CosmosDb 是否要求他们拥有 setter。
  • 是的,在对类执行 ReadItemAsync() 时,这些属性需要是公共属性。如果这是一个问题,那么您需要在数据层中创建仅限内部的类,然后返回带有只读 getter 的公共版本。
猜你喜欢
  • 2019-06-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
  • 2017-05-25
  • 2016-03-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多