所有领域实体对象的抽象基类

5
我在一些领域对象模型中看到,为了获得其标识,创建了一个抽象基类(实现了Equals和GetHashCode),供所有领域实体对象继承。
我不清楚为什么需要这个基类,以及何时和为什么应该使用它。您能为我提供一些见解或引用一些相关链接吗?
现在我明白了重写相等性的优点(这个链接有帮助:http://en.csharp-online.net/CSharp_Canonical_Forms—Identity_Equality)。
回到领域驱动设计,我想进一步扩展我的问题:
我有一个客户实体,我使用guid作为标识。
如果我创建两个具有完全相同详细信息的客户实例,由于我使用guid作为标识,它们将是两个不同的对象。但是,由于它们具有相同的属性,它们应该是同一个对象(或者将它们保持独特和分开是更好的DDD实践?)
我试图理解是否应通过它们的完整属性值匹配来处理两个对象的相等性。如果我朝着这个方向前进,那么我就要在子类级别上覆盖基类的相等性并实现这些条件,或者将实体的标识设置为这些属性值的字符串或哈希码表示,并使用基类的相等性。
我可能有点偏离主题,所以提前感谢您的耐心。

请提供您所指的详细信息。您看到的不是所有人都知道的行业惯例,而更有可能是与您未向我们提供的详细信息相关的特定事项! - John Saunders
希望这样更好 - 不过我不太清楚应该在哪里发布第二个问题作为这个问题的后续,所以我只是通过编辑我的原始问题来放置它。 - learning_ddd
5个回答

3

这里使用的术语相等有多重含义:

1)标识相等

如果您有两个相同客户的实例,则它们都应具有相同的GUID值-这是确保您正在使用相同实体的唯一方法。实际上,将始终存在相同实体的不同实例(例如在不同计算机上运行的多用户应用程序)。

2)相似相等

这是您检查两个实例是否具有完全相同的值。例如,如果两个员工正在查看同一个客户,并且第一个人修改并保存了它,则两个人将看到不同的数据。他们都对同一个客户感兴趣,但数据变得过时。

对于(2),您绝对需要一种机制来进行检查。您可以比较每个属性(昂贵),或者您可以使用“版本”属性来检测更改(请参见NHibernate的乐观锁定机制)。

我认为你的例子有些牵强,可能会让你偏离DDD的更重要方面。如果你感兴趣,我销售一款工具,可以帮助更轻松地理解DDD概念。

2
如果它们是实体,则应比较对象的ID和它们的属性,如果它们是值对象,则应比较它们的属性。这意味着您不必从基本实体继承您的值对象,但对于实体来说最好创建一个。

如何确定类是实体还是值对象?您应该回答一个问题:如果它们具有相同的属性集,则此类对象是否相等?如果是,则它们是值对象。例如,即使两个人具有相同的姓名和出生日期,也不相等 - 无论如何都应将它们视为不同的实体。但是,如果你有一枚25美分硬币,你可能不关心你拥有哪个精确的金属块,它们都只是25美分硬币。

有一篇很棒的文章详细描述了这些内容:domain object base class


1
如果您正在遵循DDD,那么我认为您应该通过它们的ID(身份)检查对象的相等性。这是因为域实体是由其标识定义和跟踪的,而不是通过属性定义的。因此,无论它们与其他对象多么相似,它们仍然是不同的实体。
另一个您需要了解的概念是值对象。它是描述对象特征并且不需要标识的内容。例如:地址、金钱、颜色。

0

你提到了为什么它被使用的两个原因。

对于Equals,您可能不希望始终检查实际引用是否相等,因为它可能不相等。您可能要使用某种标识属性(如公共int ID)来检查是否有两个实体相等。基本的Equals实现只会检查这两个引用是否相等。

至于哈希码,它是一种在使用哈希算法等时唯一标识给定对象/类型的方式。


0

我会只检查身份是否相等,因为这样可以让你拥有一个包含前后情况的实体实例,有时非常方便。要检查实例是否已更改,可以使用Dirty标志。

希望对你有所帮助, Jonathan


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接