我在一些域对象模型中看到,为所有域实体对象创建了一个抽象基类(实现了Equals和GetHashCode),以便继承它们以获得它们的身份。
我不清楚为什么需要这个基类以及何时以及为什么应该使用它。您能否就此提供一些见解或向我推荐一个关于此
的链接由于
现在我了解覆盖Equality的优势(此链接有助于http://en.csharp-online.net/CSharp_Canonical_Forms - Identity_Equality)
回到域驱动设计我想稍微扩展我的问题;
我有一个客户实体,我使用guid作为身份。
如果我创建具有完全相同细节的2个客户实例,因为我使用guid作为标识,它们将是两个不同的对象。但是因为它们具有相同的所有属性,所以它们应该是同一个对象(或者它是一种更好的ddd实践,以保持它们的独特性和独立性?)
试图理解我是否应该通过完全属性值匹配来处理两个对象的相等性。如果我朝着那个方向前进,那么我正在寻找在子类级别上覆盖基类的等式并实现这些条件,或者让实体的标识为字符串或哈希码(?)表示所有值的值这些属性并使用基类的等式。
我可能会离这儿很近,所以提前感谢你的耐心。
答案 0 :(得分:3)
这里重复使用术语相等:
1)身份的平等
如果您有同一个客户的2个实例,则它们都应具有相同的GUID值 - 这是确保您使用同一个实体的唯一方法。实际上,同一个实体总会有不同的实例(例如,在不同机器上运行的多用户应用程序)。
2)同一性的平等
这是您检查2个实例具有所有相同值的位置。例如,如果2名工作人员正在查看同一客户,并且第一人修改了&保存它,人们都会看到不同的数据。他们都对同一个客户感兴趣,但数据变得陈旧。
对于(2),你肯定需要一种机制来进行检查。您可以比较每个属性(昂贵),或者您可以使用'version'属性来检测更改(请参阅NHibernate’s optimistic locking mechanism)。
我认为你的例子有点做作,可能会让你远离DDD更重要的方面。如果您有兴趣,I sell a tool可以帮助您更轻松地掌握DDD概念。
答案 1 :(得分:1)
如果您关注DDD,我相信您应该通过ID(身份)检查对象是否相等。这是因为域实体是由其身份而非属性进行主要定义和跟踪的。因此,无论它们与其他对象有多么相似,它们仍然是不同的实体。
您想要检查的另一个概念是值对象。它描述了对象的特征,不需要身份。例如,地址,金钱,颜色。
答案 2 :(得分:1)
如果对象的ID是实体及其属性(如果它们是值对象),则应该比较它们的ID。这意味着您不必从基础实体继承您的价值对象,但对于实体来说,最好创建一个。
如何理解类是实体还是值对象?你应该回答一个问题:如果这些类具有相同的属性集,那么它们是否相等?如果是,则它们是值对象。例如,即使他们有相同的姓名和出生日期,两个人也不平等 - 无论如何你应该将他们视为不同的实体。但是如果你有25美分的硬币,你可能不在乎你有什么精确金属,它们都只有25美分硬币。
有一篇很棒的文章描述了细节:domain object base class
答案 3 :(得分:0)
你指出了使用它的两个原因。
对于Equals,您可能不想总是检查实际参考是否相等,因为它可能不是。您可能希望使用某种标识属性(如public int ID)来检查以查看2个实体是否相等。 Equals的基本实现只是检查2个引用是否相等。
就哈希码而言,它是一种在哈希算法等中使用它时唯一标识给定对象/类型的方法。
答案 4 :(得分:0)
我只能检查身份,因为它允许你拥有一个包含前后情况的实体实例,这有时非常方便。要检查实例是否已更改,可以使用Dirty标志。
HTH, 乔纳森