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

时间:2009-03-15 00:56:26

标签: c# domain-driven-design

我在一些域对象模型中看到,为所有域实体对象创建了一个抽象基类(实现了Equals和GetHashCode),以便继承它们以获得它们的身份。

我不清楚为什么需要这个基类以及何时以及为什么应该使用它。您能否就此提供一些见解或向我推荐一个关于此

的链接

由于

现在我了解覆盖Equality的优势(此链接有助于http://en.csharp-online.net/CSharp_Canonical_Forms - Identity_Equality)

回到域驱动设计我想稍微扩展我的问题;

我有一个客户实体,我使用guid作为身份。

如果我创建具有完全相同细节的2个客户实例,因为我使用guid作为标识,它们将是两个不同的对象。但是因为它们具有相同的所有属性,所以它们应该是同一个对象(或者它是一种更好的ddd实践,以保持它们的独特性和独立性?)

试图理解我是否应该通过完全属性值匹配来处理两个对象的相等性。如果我朝着那个方向前进,那么我正在寻找在子类级别上覆盖基类的等式并实现这些条件,或者让实体的标识为字符串或哈希码(?)表示所有值的值这些属性并使用基类的等式。

我可能会离这儿很近,所以提前感谢你的耐心。

5 个答案:

答案 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, 乔纳森