我刚刚开始研究域驱动设计,很可能我对实体/价值观的分歧是错误的,所以如果是这样,请告诉我。
根据我的理解,由于其身份完全由其属性定义,因此Address是典型的值对象。根据我的理解,这意味着不应该有地址的单独存储库或数据访问对象。
这给我带来了两难境地,因为在我的情况下,地址包含一个国家/地区,其中国家/地区具有名称和国家/地区代码,国家/地区代码列表应该从数据库中加载。
我的问题是,我该如何设计?我希望人们能够使用new运算符创建地址,但我不想为国家创建数据访问对象,如果我这样做,我当然不希望在地址对象中添加对它的引用。 / p>
我有一些想法,但我想听听任何人的建议。
答案 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)
...