8

我需要澄清一些事情。

有人员聚合,2 个 VO(国家,州省)。

我想在我的表示层中加载所有国家(我正在使用 mvc)

Evan 说您只使用存储库 (IPersonRepository) 来处理根实体(它应该始终只返回对聚合根的引用)

   public interface IPersonRepository()
   {
     void savePerson(Person p);
     void removePerson(Person p);
     Ilist<Person> getPerson();
   }

我通常会做什么来解决这个问题:

在 IPersonRepository 中添加这个方法

IList<Country> LookupCountrysOfPerson();

在 Infra 层实现域接口,如下所示:

public IList<Person> LookupCountrysOfPerson()
{
    return Session.CreateQuery("from Countrys").List<Person>());
}

我的搭档说我错了。

有时你必须牺牲你的领域模型来完成一些任务

做这个的最好方式是什么?

请用代码!:)

4

4 回答 4

8

我会说你不太可能需要国家成为一个实体。我怀疑国家只不过是参考数据,就像一个人的头衔一样。您的域中是否存在与国家/地区相关的行为?我怀疑这只是印在字母/信封上的东西。

这个问题有点类似于我不久前回答的这个问题:

简单的聚合根和存储库问题

我的建议是您实现一个查找服务,您的客户可以使用该服务并缓存该服务。忽略 DDD 的规则以及与聚合或存储库有关的任何事情。正如其他人所提到的,这就是 CQRS 的意识形态发挥作用的地方。客户端不必通过域来获取数据。该域纯粹是事务性的,不是为查询而设计的。

本文解释了如何为通常在 UI 中填充下拉列表的事物(即标题、国家等)构建一个通用查找服务以获取参考数据

http://wtfperminute.blogspot.com/2011/02/working-with-reference-data-lookups.html

于 2011-03-30T14:36:46.390 回答
5

Evans 还说(第 170 页)“一个像 Location 这样基本的实体可能被许多对象使用,原因有很多……”

出于上述原因,我还会考虑将 Country 设为实体。也许更重要的是,它是一个低级对象。您甚至可能还通过配置而不是通过任何实际的域活动来提供 Country。因此,我会将其从 Person 中删除并使其成为独立实体。

同样对于这种类型的对象,您可能真的不需要专用存储库,请考虑创建一个查找服务,为一组具有这种性质的相似对象提供查询访问权限。

于 2011-03-30T06:21:30.677 回答
2

如果在您的域中国家实际上是一个 VO(您不想在国家名称更改等中维护一个身份线程),这是最常见的情况,我会在数据访问层中添加一个专门的类来返回作为 VO 的所有国家/地区的列表。我还将向国家实体添加缓存(NHibernate 中的二级缓存)并列出所有国家/地区查询,这样我就不必每次都访问数据库。

实际上,这就是 CQRS 真正闪耀的地方。CQRS 承认您不必通过域层来获取一些用于演示目的的数据。在 CQRS 中,您只需获取一些数据。

于 2011-03-30T13:32:33.203 回答
1

听起来国家实际上并不是这里的价值对象;它们具有不同的身份,并且对于您的Person对象之外的业务目的很重要。他们应该成为实体,并以适合他们的方式对待。

这样想:假设某个动荡的国家推翻了现任独裁者并改名。对象对 a的Person引用Country应该仍然有效,因为aCountry不是由其属性(即表示其名称的字符串)定义的,而是由其标识定义的。

于 2011-03-29T20:48:04.583 回答