如何处理需要在数据库中查找数据的值对象

时间:2009-02-15 15:46:49

标签: architecture domain-driven-design

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

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

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

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

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

4 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

首先让我说,我对域驱动设计的唯一体验是几分钟前阅读维基百科的文章。话虽如此,这是我对你的问题的看法:

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

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

答案 2 :(得分:1)

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

你不应该担心国家只在地址中使用。将其作为实体本身并没有错。主要问题是:您认为国家是具有身份的东西,还是仅仅由属性定义?如果您有两个国家/地区具有相同的名称(以及相同的国家/地区代码),您能看到任何差异吗?

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

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

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

希望这有帮助

答案 3 :(得分:0)

  

这给我带来了进退两难的困境   我的情况一个地址包含一个国家   国家有名字和   国家代码和清单   应该加载国家/地区代码   来自数据库。

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

myDropDown(包含Country对象列表)selected object value = 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)
    ...