【发布时间】:2011-08-31 09:20:40
【问题描述】:
我在创建一个可公开访问的网站时尝试使用域驱动设计。我遇到的一个问题是试图弄清楚我的模型的聚合根应该是什么。我很清楚哪些对象是实体对象,哪些对象是值对象。
与大多数公共网站一样,我的网站不允许每个用户查看网站中存储的每条信息。相反,他们只能看到自己拥有的信息。对于我的站点,用户将创建“项目”,他们也可以与其他用户共享。然而,用户仍然只能看到他们创建或受邀加入的项目中的信息。我的模型中的所有其他对象都存在于一个项目中,如果一个项目被删除,它包含的所有对象也应该被删除。
这是否意味着我应该拥有一个主要的“Project”聚合根类型和一个“ProjectRepository”存储库?每次请求我网站上的任何页面时,加载整个项目对我来说似乎效率低下。实际上,这不是什么大问题,因为我使用的是 NHibernate,它只会延迟加载项目中请求的项目。然而,让网站的效率如此依赖于使用延迟加载的 ORM 似乎是糟糕的设计。
这里有一个更新,希望能让我的问题更清楚。
首先,我试图了解我的项目类型是否应该是我的模型的聚合根。项目可以单独存在,而报告必须存在于项目中。如果删除项目,则应删除相应的报告。这是否意味着 Project 可以或应该是聚合根?这个我不是很清楚。
如果 Project 是聚合根,那么 Report 应该不正确?据我了解,根不应嵌套在 DDD 中。此外,只允许从存储库中检索聚合根。因此,如果 Report 不是聚合根目录,那么我不应该有 ReportsRepository,而应该只通过从 ProjectsRepository 检索到的项目访问报告。因此,即使页面只需要来自单个报表的数据,它也需要从 ProjectRepository 加载整个项目才能获取报表。
此外,如果 Project 是包含 Reports 的聚合根,则也可以设置从 ProjectRepository 中删除 Project 以删除它包含的 Reports。但是,如果 Project 和 Report 都是聚合根,那么在删除 Project 时不允许 ProjectRepository 删除 Reports 会打破聚合之间的界限吗?聚合根及其对应的存储库不是应该相互独立吗?
【问题讨论】:
-
"然而,让网站的效率如此依赖于使用延迟加载的 ORM 似乎是糟糕的设计" 为什么?这是扎实的技术。一个基本的 SQL “SELECT...WHERE...”实际上是延迟加载数据子集。它出什么问题了?你能提供更具体和具体的问题吗?
-
好点,我只是没想到那样。那么,也许有一个单一的“项目”聚合根是有意义的?如果我不使用 NHibernate 调用 ProjectRepository.GetProject(int id) 将是一个相当繁重的过程来构建整个项目对象。几乎每个页面请求都需要调用它。 NHibernate 没有任何问题。我只是认为存储库模式的重点是允许存储库的实现发生变化而不会产生重大影响。
-
@Eric Anastas:“在不产生重大影响的情况下实施存储库进行更改”?我觉得你的水平太高了。你为什么专注于这些 Big Aggregate 对象?为什么项目聚合是问题域中唯一的东西?这不会分解吗?
-
确实可以分解项目。一个项目将包含问题、报告和许多其他类型的对象,这些对象本身似乎可以是聚合根。然而,这些对象也总是与一个项目相关联,如果它们的父项目被删除,也需要被删除。或者换句话说,报告或问题永远不会单独存在,它将始终与项目相关联。
-
@Eric Anastas:“与项目相关”似乎并不表示您必须为每个页面视图构建整个项目。 “如果他们的父项目被删除,也需要被删除”似乎并不表示您必须为每个页面视图构建整个项目。我不清楚为什么整个项目必须出现在任何给定的页面视图中。此外,我不清楚这与 DDD 有何关系。你能更新这个问题来解释你的推理吗?
标签: nhibernate domain-driven-design aggregate aggregateroot