5

我刚开始研究领域驱动设计,很可能我对实体/价值划分的理解是错误的,所以如果是这样,请告诉我。

据我了解,由于其身份完全由其属性定义,因此 Address 是典型的值对象。据我了解,这意味着不应该有单独的存储库或地址的数据访问对象。

这给我带来了两难境地,因为在我的例子中,地址包含一个国家,其中一个国家有一个名称和一个国家代码,并且应该从数据库中加载国家代码列表。

我的问题是,我该如何设计这个?我希望人们能够使用 new 运算符创建地址,但我不想为国家/地区创建数据访问对象,如果我这样做了,我当然不想在地址对象中引用它。

我有一些想法,但我想听听任何人可能有的任何建议。

4

4 回答 4

3

DDD 中没有任何内容阻止值对象持有对实体的引用。因此,您的地址将引用国家实体。

于 2009-02-15T16:18:27.063 回答
1

首先让我说,我对领域驱动设计的唯一经验是几分钟前阅读了 Wikipedia 文章。话虽如此,以下是我对您的问题的看法:

我同意地址对象不应该需要任何数据访问对象,那么处理国家代码并根据用户输入构建地址对象的地址工厂怎么样?这样,工厂将保存数据访问对象,并且您的地址对象可以保持值唯一。

如果根据 DDD 这不是犹太洁食,请告诉我。我很想知道社区的其他人会想出什么。

于 2009-02-15T16:03:03.107 回答
1

采用 DDD 方式,您会首先考虑应用程序的需求,然后从那里构建模型。

您不必担心 Country 仅在 Address 中使用。使其成为实体本身并没有错。主要问题是:您认为国家是具有身份的事物,还是仅由属性定义?如果您有两个具有相同名称(和相同国家代码)的国家/地区,您能看出有什么区别吗?

也许您应该考虑将 Country 设为值对象。它不会阻止您从数据库中加载一些国家/地区的存储库列表,或根据其代码加载国家/地区。在实施方面,您的存储库仍然可以从数据库中加载国家列表一次并将其缓存在内存中。或者它可以对其进行硬编码,或者从 XML 中读取。您的域模型不会在意。

您可能会在 Address 上创建一个工厂方法,该方法接受国家代码以及其他参数。然后它将使用存储库创建一个 Country 实例并返回一个正确的 Address 对象。

考虑聚合也可以产生一些关于存储库布局的想法。

希望这可以帮助

于 2009-02-17T13:46:45.117 回答
0

这给我带来了两难境地,因为在我的例子中,地址包含一个国家,其中一个国家有一个名称和一个国家代码,并且应该从数据库中加载国家代码列表。

Address 对象不会将国家列表作为其属性。相反,它将具有国家对象的单个实例。表示层将提供 Country 对象列表,可能位于下拉列表中。在加载一个特定地址时,您可以将下拉列表的值设置为与国家对象的国家 ID 相等,该国家对象是地址对象的一个​​属性。换句话说:

myDropDown 的(包含 Country 对象列表)选定对象值 = address.Country 或 myDropDown 的键值 = address.Country.ID

现在,要填充表示层,您的数据访问层应该提供一个函数,该函数返回 Country 对象的原始列表。在 .NET 方式中,它类似于:

Namespace Dal

    Public NotInheritable Class Countries
    ...
    Public Shared Function Read(ByVal countryId as Integer) As BusinessObjects.Country
    ...
    Public Shared Function ReadList() As List(Of BusinessObjects.Country)
    ...
于 2009-02-15T16:02:37.177 回答