【问题标题】:Domain Driven Design - Large child collections领域驱动设计 - 大型子集合
【发布时间】:2014-05-07 20:04:13
【问题描述】:

问题

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

Employee 聚合根

  • Announcements收藏
  • 直接Messages收藏

Product聚合根

  • Stock物品收藏

等等。等等。

我在想什么

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

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

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

【问题讨论】:

  • 聚合根不是容器,存储库是。

标签: c# domain-driven-design repository aggregateroot


【解决方案1】:

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

一般来说,我会说,一开始就不应该拥有这些大型收藏品。一方面,加载它们将需要更好地花在其他地方的资源(内存、cpu、带宽)。从更实用的角度来看,无论如何,人们往往不会一次处理大量的事情,当你把事情分解成工作单元时,即使是计算机也可以做更多的工作。因此,尽量远离大型收藏品,并始终质疑“为什么”您首先需要它们。

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

话虽如此,有时您可以稍微改变规则,但应该很少。

【讨论】:

  • 老实说,我不需要大型收藏,这些收藏中的大部分将根据需要进行分页和加载(可能以 facebook/twitter 的风格)。那么我的第二个选择呢?公告只能由特定组中的员工创建,StockItems 具有只能在特定条件下转换到其他状态的状态。等等等等。行为是他们的并且封装在领域模型中,麻烦在于组织它的连贯性。
【解决方案2】:

看看来自 Vaughn Vernon 的论坛 DDD 示例。他从聚合根中模拟了大型集合。创建是通过聚合上的工厂方法完成的,以保持对某些事物的控制,例如论坛关闭时无法创建讨论。操作是通过 AR 论坛完成的(例如 startDiscussion 和moderatePost)。

该方法返回一个实体(Post),应用服务需要将其保存在单独的存储库(PostRepository)中。现在您可以拥有大型集合,而无需每次都加载。

https://github.com/VaughnVernon/IDDD_Samples/tree/master/iddd_collaboration/src/main/java/com/saasovation/collaboration/domain/model/forum

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-01
    • 2013-09-16
    • 2010-11-30
    • 2011-10-06
    相关资源
    最近更新 更多