>表格(有自己的清单)部分;
>部分 – > (有自己的列表)组;
>组 – > (有自己的问题清单);
>问题 – >(可以有自己的子问题列表)问题;
>问题 – > (有自己的清单)答案;
>答案 – > (有自己的列表)Answer_Details;
> Answer_Detail – > (可能有自己的子细节列表)Sub_Answer_Details.
每个对象都有超过15个属性,如果没有父对象,每个属性都没有意义.根据DDD,我认为Form实体应该是Aggregate Root,所有其他对象应该是值对象.这意味着我只需要一个表单实体的存储库.在这种情况下,FormRepository将与子对象的各种CRUD方法混杂在一起.我的推理是否适合DDD?我最终得到了一个非常广泛的聚合物吗?我相信这样的表示很容易导致性能问题.
我最终得到了一个非常广泛的聚合物吗? – 如果现实情况复杂,并且您的领域模型尽可能最好,那么最终会得到一个复杂的聚合根.
是的,Form应该是聚合根.
所有其他对象应该是值对象 – 错误,所有其他对象应该是非聚合根实体(带有Id),而没有用于获取它们的存储库.值对象没有Id,值对象的相等性仅由其属性值确定,而不是由Ids的等式确定(更多信息here).
在这种情况下,FormRepository将混杂着各种用于子对象的CRUD方法 – 不,存储库应仅包含关于聚合根的方法,即Get< T>.,保存< T>其中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()将从DB加载所有部分,但不加载组和其余部分.对于查询,您将创建一个FormDto(数据传输对象)和其他可能被展平的dtos来获取所需形式的数据(可能与您的实体结构不同,UI可能会驱动dto结构).有关DDD / CQRS / NHibernate / Repository的信息,请查看我的blog