Nhibernate DDD:所有东西都应该适合实体或值对象吗?

Nhibernate DDD:所有东西都应该适合实体或值对象吗?,nhibernate,orm,domain-driven-design,Nhibernate,Orm,Domain Driven Design,我正在努力学习DDD,或者至少是我对它有限的理解 不过,我在把一些东西装进DDD盒时遇到了麻烦 例如:我有一个用户实体。这个用户实体有一个对UserPreferencesInfo对象的引用——这只是一个类,它包含一系列关于用户首选项的属性。这些属性是完全不相关的,不同的是它们都是用户的首选项(不像地址VO,在地址VO中,所有属性构成一个有意义的整体) 问题是-这个UserPreferencesInfo对象是什么 1) 显然,它不是一个实体(我只是将其作为“组件”存储在fluent nhibern

我正在努力学习DDD,或者至少是我对它有限的理解

不过,我在把一些东西装进DDD盒时遇到了麻烦

例如:我有一个用户实体。这个用户实体有一个对UserPreferencesInfo对象的引用——这只是一个类,它包含一系列关于用户首选项的属性。这些属性是完全不相关的,不同的是它们都是用户的首选项(不像地址VO,在地址VO中,所有属性构成一个有意义的整体)

问题是-这个UserPreferencesInfo对象是什么

1) 显然,它不是一个实体(我只是将其作为“组件”存储在fluent nhibernate speak中(即,与用户实体存储在同一个DB表中)

2) VO?我知道Value对象应该是不可变的(所以你不能保存它们,只需要重新创建它们)。例如,当对象是一个地址时(地址属性形成一个有意义的“整体”),这是完全有意义的。但就用户偏好而言,我认为这是没有意义的。可能有100个属性(实际上)这个对象上可能有20个属性-为什么每当我需要更改一个属性时,我都要放弃一个属性来重新创建对象

我觉得我需要打破这里的规则来得到我需要的东西,但我真的不喜欢这样的想法(这是一个很滑的斜坡!)。我是不是遗漏了什么


谢谢

据我所知,
UserPreferenceInfo
User
实体的一部分。Ergo User entity是一个聚合根,它与
UserPreferenceInfo
和其他对象一起使用
UserRepository
作为一个整体进行检索或保存

就我个人而言,我认为
UserPreferenceInfo
是实体类型,因为它具有标识-它可以从存储库中更改、保存和检索,并且仍然被视为相同的对象(即具有标识)。但这取决于你对它的使用

不管对象在DAL中是如何表示的,它是存储在单独的表中还是存储在其他表的一部分中。DDD的好处之一是坚持不懈,这通常是一件好事


当然,我可能错了,我也是DDD的新手。

100属性听起来很多


尝试将
UserPreferenceInfo
分解为更小(更内聚)的类型,这些类型很可能/希望可以作为VOs进行管理。

我想说,UserPreferenceInfo实际上是用户聚合根的一部分。UserRepository应该负责持久化用户聚合根

值对象只需要在共享其值时更新(在对象模型中)。如果您检查类似的UserPreferenceInfo并将该用户与之关联,而不是每次都插入一个新的UserPreferenceInfo,则是一个示例场景。如果值对象表变得太大并增加速度/存储问题,共享值对象是有意义的。共享的价格在插入时支付。 在DAL中抽象此过程是合理的


如果您没有保存值对象,那么没有什么反对更新的。

这是我的两分钱。简短回答:UserPreferenceInfo是一个值对象,因为它描述对象的特征。它不是实体,因为不需要随时间跟踪对象实例

更详细的回答:一个拥有100多个不相关属性的对象不是很DDD。尝试将相关属性组合在一起以形成新的VO,否则您也可能会发现新的实体

DDD的另一个特点是首先要有很多设置属性。试着找出行动的本质,而不是仅仅设定价值。例如:

// not ddd 
employee.Salary = newSalary;

// more ddd
employee.GiveRaise(newSalary);
另一方面,您可能有正当的理由拥有一堆只不过是getter和setter的属性。但是可能有比DDD更简单的方法来解决这个问题。从DDD中获取最佳模式和想法没有什么错,但要放松一点所有的“规则”,特别是对于更简单的领域

问题是-这个UserPreferencesInfo对象是什么

我不知道NHibernate是如何支持这个案例的,但是一些ORM支持它们的特殊概念。例如,DataObjects.Net包含概念。在NH,你似乎需要这样的东西。

答案1(实用的)

我是DDD的坚定支持者,但不要强迫它。您已经认识到,不可变VO添加的工作比需要的多。DDD旨在利用复杂性,但在这种情况下,需要管理的复杂性非常小

我只需将
UserPreferencesInfo
视为一个实体,并从
用户
集合中引用它。您可以选择将其存储为组件还是存储在单独的表中

依我看,整个实体对VO的辩论都是毫无意义的。在6个月的时间里,另一个开发人员不太可能看到您的代码并说“WTF!他没有使用不可变的VOs!他到底在想什么!!”

答案2(DDD纯粹主义者)

UserPreferencesInfo
实际上是业务领域的一部分吗?其他人提到了切除这个物体。但是如果您坚持使用纯DDD,您可能需要确定哪些首选项属于哪个有界上下文


这反过来可能会导致添加服务层,在您意识到这一点之前,您已经为一个非常简单的问题过度设计了解决方案…

首次在博客上发布。希望我做得对

无论如何,由于您没有向我们展示UserPreferencesInfo对象,我不确定它是如何构造的,这样您就可以在其中包含可变数量的内容

如果是我,我将创建一个名为UserPreference的类,其中包含id、userid、key、value、displaytype以及您可能需要的任何其他字段。这是一个实体。它有一个id,并且绑定到