【问题标题】:Entity/value object selection实体/值对象选择
【发布时间】:2009-04-27 15:51:37
【问题描述】:

在领域驱动设计中,具有标识的对象是一个实体是众所周知的。例如,任何人都会有多种形式的身份(姓名等)。

但是值对象是那些没有身份的对象。一个常见的值对象是地址,但是地址没有身份。但是在数据库层,我们可以有一个复合键。这个概念在 DDD 中有效吗?它将通过道路名称、邮政编码和门号的组合来识别地址(省略城镇和城市等信息)。金钱将是另一个价值对象。

区别似乎在于没有单一可识别字段的对象,而值对象往往实际上并不属于实体。例如,“我”(替换为我的名字)可能会穿鞋等,但“我”不是鞋、衬衫等 (http://www.lostechies.com/blogs/joe_ocampo/archive/2007/04/23/a-discussion-on-domain-driven-design-value-objects.aspx)。

这是思考问题的正确方式吗?此外,通过这种心态/方法,我可以将其应用于 C# 中的值/引用类型选择。不过,我还不如使用 DDD 方法?

谢谢

【问题讨论】:

    标签: domain-driven-design


    【解决方案1】:

    我认为您对实体和值类型之间的区别的概念是正确的,因为它们在域驱动设计中被理解(尽管我在这方面远非专家 - 也许更好地说您符合我对这些概念的理解) .但是,在选择将这些对象建模为 C# 中的引用还是值时,我建议不要将其用作决定性指标。

    值和引用类型之间的主要区别在于,值类型在传递给方法时会被复制。这意味着它们更有可能位于堆栈而不是堆上,并且传递的成本可能更高;因此,尺寸成为考虑的因素。建议结构的大小应小于 16 字节(在注释底部 here),而综合地址结构(门牌号、门牌名称、街道区域、城市、国家等...)将很容易打破这一点.

    话虽如此,entity:value :: class:struct 的语义非常相似,我可以看到以这种方式建模数据的很多好处(住在同一地址的两个人不会共享该地址,因为更改一个人的地址不应该更改另一个人的地址。因此,将地址作为结构将强制执行这种分离。而应用程序中一个人的所有实例都应该指向同一个人) .但是有性能和内存方面的考虑。或许不可变类更适合这些值类型?

    总结一下:DDD 中实体和值的区别在于对象是什么。在代码中应该基于你打算用它做什么。

    【讨论】:

    • 实体/值对象的区别有助于在 C# 中的类和结构之间进行选择。我确信有一些考虑可能会导致异常(选择相反的类型,否则,关于对象的所有其他事实使它适合一种类型)。但是,可以修改地址(建筑物)。这不应该是可变的吗?引擎可能是一个结构体和较小项的组合,但它也可以修改。
    • 老实说,我不确定我是否完全遵循您的评论,但关于地址的可变性,我建议使用不可变类的原因是它阻止了 A 上的地址更改被转移的可能性当 B 共享地址类的实例时,将其发送给 B,因为这会迫使您为 A 创建一个新的唯一实例。这是您从结构中获得的主要优势,我试图证明有可能获得与类的行为相同。
    • 从业务角度来看,这有点棘手。例如,一个家庭会有一个房子,但这也是一个引用类型。当孩子们还小的时候,他们不会搬家,所以房子是一个共同的参考。
    • 值对象是不能独立存在的东西。因此,服装只能通过 Person 对象访问,同样,通过房主或人访问 Home,汽车是 Driver 的财产。但是,发动机是汽车的属性,所以这应该是 vo,但发动机本身可以有几个较小的组件(实际上很多)。同一家公司也有超过 1 名员工住在同一所房子里的情况。我的想法是结构体应该是一个在现实生活中不可变的对象。
    • 我同意 DDD 中的值对象和 OOP 中的结构的语义非常相似,但是我重申,VO 不共享的结构的定义属性是它应该是轻量级的否则会对性能产生不利影响。因此,当您想要为具有大量数据(例如地址)的 VO 建模时,我仍然建议使用不可变类而不是结构。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 2010-10-04
    • 2013-11-18
    • 1970-01-01
    相关资源
    最近更新 更多