我正在尝试关注DDD,或者至少我对它的理解有限。
我在将一些东西放入DDD盒子时遇到了麻烦。
一个例子:我有一个用户实体。此用户实体具有对UserPreferencesInfo对象的引用 - 这只是一个包含许多有关用户首选项的属性的类。这些属性是相当无关的,除了它们都是用户首选项(不像地址VO,其中所有属性形成一个有意义的整体)。
问题是 - 这个UserPreferencesInfo对象是什么?
1)显然它不是一个实体(我只是将它作为'组件'存储在流利的nhibernate说话中(即在与用户实体相同的数据库表中)。
2)VO?我知道Value Object应该是 Immutable (所以你不能把它们装起来,只是新建它们)。当对象是例如地址时(地址属性形成有意义的“整体”),这就完全有意义。但在UserPreferencesInfo的情况下,我认为这没有意义。 可能有100个属性(实际上)这个对象上可能有20个属性 - 为什么我需要在需要更改一个属性时丢弃重新创建对象?
我觉得我需要在这里打破规则以获得我需要的东西,但我真的不喜欢这个想法(这是一个滑坡!)。我在这里错过了什么吗?
谢谢
答案 0 :(得分:6)
答案1(实用的)
我是DDD的忠实拥护者,但不要强迫它。您已经认识到,不可变的VO添加的工作量超出了要求。 DDD旨在利用复杂性,但在这种情况下,管理的复杂性非常低。
我只是将UserPreferencesInfo
视为实体,并从User
聚合引用它。无论您将其存储为组件还是单独的表都是您的选择。
答案2(DDD纯粹主义者)
UserPreferencesInfo
实际上是业务域的一部分吗?其他人提到了解决这个问题。但如果你坚持使用纯DDD,你可能需要确定哪些偏好属于 Bounded Context 。
这反过来可能会导致添加服务图层,在您知道之前,您已经过度设计了解决方案,以解决一个非常简单的问题...
答案 1 :(得分:4)
这是我的两分钱。简短回答:UserPreferenceInfo是一个值对象,因为它描述了对象的特征。它不是一个实体,因为不需要随着时间的推移跟踪对象实例。
更长的答案:具有100多个不相关的属性的对象不是非常DDD-ish。尝试将相关属性组合在一起以形成新的VO,或者您也可以发现新的实体。
另一种DDD气味首先是具有很多固定属性。尝试找到动作的本质而不是仅设置值。例如:
// not ddd
employee.Salary = newSalary;
// more ddd
employee.GiveRaise(newSalary);
另一方面,你可能有合理的理由拥有一堆不仅仅是getter和setter的属性。但是,有可能比DDD更简单的方法来解决问题。从DDD中获取最佳模式和想法并没有什么不妥,但放松了所有“规则”,特别是对于更简单的域。
答案 2 :(得分:2)
我会说UserPreferenceInfo实际上是User聚合根的一部分。 UserRepository应该负责持久化User Aggregate Root。
只有在共享值时,才需要在对象模型中新建值对象。如果您检查类似的UserPreferenceInfo并将User与之关联,而不是每次都插入一个新的,则可以采用一种示例方案。共享值对象有意义,如果值对象表变大并提高速度/存储问题。分享的价格是在Insert上支付的。 在DAL中抽象这个程序是合理的。
如果你没有抨击价值对象,就没有什么可以反对更新。
答案 3 :(得分:1)
据我了解,UserPreferenceInfo
是User
实体的一部分。 Ergo用户实体是一个聚合根,它使用UserRepository
作为整体检索或保存,以及UserPreferenceInfo
和其他对象。
就个人而言,我认为UserPreferenceInfo
是实体类型,因为它具有身份 - 它可以从存储库中更改,保存和检索,并且仍然被视为同一个对象(即具有身份)。但这取决于你对它的使用。
恕我直言,如何在DAL中表示对象 - 它是存储在单独的表中还是存储在其他表的一部分中。 DDD的一个好处是持久性无知,通常是一件好事。
当然,我可能错了,我也是DDD的新手。
答案 4 :(得分:1)
问题是 - 这个UserPreferencesInfo对象是什么?
我不知道NHibernate如何支持这种情况,但是一些ORM支持它们的特殊概念。例如,DataObjects.Net包含Structures概念。看起来你在NH需要这样的东西。
答案 5 :(得分:1)
首次在博客上发帖。希望我做得对。
无论如何,既然你没有向我们展示UserPreferencesInfo对象,我不确定它是如何构造的,你可以在其中包含可变数量的东西。
如果是我,我会创建一个名为UserPreference的类,包含id,userid,key,value,displaytype以及其中可能需要的任何其他字段。这是一个实体。它有一个id并且与某个用户绑定。
然后在你的用户实体(我假设的根)中,有一个ISet。
答案 6 :(得分:0)
100个属性听起来很多。
尝试将UserPreferenceInfo
分解为更小(更具凝聚力)的类型,这些类型可能/希望可以作为VO进行管理。