是的,深度层次结构在 DDD 中很好。
我最终得到一个非常广泛的聚合体可以吗?- 如果现实如此复杂,并且你的域模型是你能想到的最好的,那么你最终会得到一个复杂的聚合根。
是的,Form
应该是聚合根。
所有其他对象应该是值对象- 错误,所有其他对象应该是非聚合根实体(带有 Id),没有存储库来获取它们。值对象没有 Id,值对象的相等性仅由其属性值决定,而不是由 Id 的相等性决定(更多信息here)。
在这种情况下,FormRepository 将被各种子对象的 CRUD 方法弄得一团糟——不,存储库应该只包含关于聚合根的方法,即Get<T> , Save<T> where T : IAggregateRoot
,一旦你得到一个聚合根的实例,你可以遍历属性和方法来获取你需要什么。例子:
var formId = 23;
var form = _formRepository.Get(formId);
var firstGroup = form.Sections.First().Group().First();
或更好
var groupIndex = 1;
var firstGroup = form.GetGroupAt(groupIndex);
在哪里
public Group GetGroupAt(int groupIndex)
{
Sections.First().Group().ElementAt(groupIndex);
}
我相信这种表示很容易导致性能问题- 如果您使用CQRS,您将从命令处理程序调用一些Form
域方法,如果您使用 NHibernate 进行实体持久性,它将默认使用延迟加载,并且只会Form
从 DB加载,然后它只会加载您真正接触过的实体,因此例如Sections.First()
会从数据库加载所有部分,但不会加载组和其余部分。对于查询,您将创建一个FormDto
(数据传输对象)和其他可能扁平化的 dto,以获取所需形式的数据(这可能与您的实体结构不同,UI 可能驱动 dto 结构)。查看我的博客以获取有关 DDD/CQRS/NHibernate/Repository 的信息