c# - 领域驱动设计 - 大型子集合

标签 c# domain-driven-design repository aggregateroot

问题

大型集合是如何在 DDD 中实现的,“感觉”它们应该是聚合根的一部分,但如果是的话,那就不切实际了?以下是一些基于我的域的示例。

员工聚合根

  • 公告集合
  • 直接消息集合

产品聚合根

  • 库存商品集合

等等。等等..

我在想什么

我希望保留从聚合根导航到这些大型集合的能力,但由于我用存储库包装我的 O/RM,延迟加载并不是真正的选择...除非我通过注入(inject)实现延迟加载要么是必要的存储库。但从我读到的关于 DDD 的内容中我知道,域实体不应该知道任何此类存储库。

另一种选择是采用这样的方法:我的域中任何潜在的大型实体集合都是一个聚合根,并且应该拥有自己的存储库,该存储库具有所需的接口(interface),以便通过以下方式获取项目集合:另一个聚合根。例如。

public interface IStockRepository
{
    IEnumerable<StockItem> FetchByProduct(Product product);
    // ...
}

最佳答案

这个“我想保留从聚合根导航到这些大型集合的能力”......是一种味道。如果你不介意我说的话,你似乎非常着迷于你的聚合的结构而不是它的行为,它正在解决什么问题,任何发挥作用的不变量。坦白说,你的感觉是错误的。这是我们结构性的、面向数据库的思维方式的残余。

总的来说,我想说,人们一开始就不应该拥有这些大型收藏。加载它们需要的资源(内存、CPU、带宽)最好用在其他地方。从更实用的角度来看,人们往往不会同时处理大量数据,甚至当你将事情分解为工作单元时,计算机也可以做更多的工作。因此,尽量远离大量收藏,并始终首先询问“为什么”需要它们。

公告可以是它自己的聚合,通过其 ID 引用员工,因此我们知道该公告是关于谁的(或为谁?)。如果公告针对的是员工群体,您可能需要研究定义该群体的内容,并对其进行明确建模。直接消息也可以是它自己的聚合,因为它可能是一个人发送给另一个人的消息。人们可以说员工的角色是消息接收者和/或发送者。同样,通过 id 引用员工聚合可能就足够了。库存商品可以单独处理,并通过其产品 ID 引用其在库存中代表的产品。员工、公告、直接消息、产品、库存商品的行为是什么?改变合作者的状态如何以及何时影响他们,为什么呢?这是解决根本原因的一种手段。找到它。

尽管如此,有时您可以稍微改变规则,但这种情况应该很少。

关于c# - 领域驱动设计 - 大型子集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23527316/

相关文章:

c# - 在 Linq-to-SQL 中映射 UDF 有任何灵活性吗?

wcf - 客户端应用程序应该使用真实模型类或 DTO 对象与 WCF 服务通信吗?

python - 如何在DDD中创建管道流程?

java - 如果文件不相等,gradle 不更新依赖项

java - dao(或者可能是存储库)应该将 id 或实体作为参数

c# - 如何在 Visual Studio 2017 项目(新的 .csproj 文件格式)中设置 `OutputPath` 而目标框架不会混淆已解析的路径?

c# - 多行插入 -> 语句超过 1000 行值的最大允许数

c# - 用户定义值类型的装箱

oop - DDD : Modeling M:N relation between two roots where the relation itself carries semantic meaning

c# - POCO;持久性无知和 DAL 依赖项 (NHibernate)