DDD,实体,模型边界

时间:2014-10-16 07:47:35

标签: domain-driven-design

我们来看这个简单的例子。我们有两个模块。一个模块是关于我们有实体Question的一些问题。此实体需要来自其他模块的实体User

当我需要列出所有问题(与作者一起)时,我的QuestionRepository也需要获取用户。问题:

  • 没有QuestionRepository创建Question Users吗?
  • 或者应该从UsersRepository获取用户,这意味着QuestionRepositoryUserRepository相关联?
  • 或者应该从某些服务中获取用户(禁止在模块之外使用repos),但这会产生包含回购的贫血服务方法吗?

还是其他什么?

编辑:请不要写关于ORM的文章。这是一个工具。我相信这个问题是关于模块之间实际共享的内容。

4 个答案:

答案 0 :(得分:1)

这取决于您希望存储库具有哪些责任,有两种方法:

  1. 您的存储库负责获取完整且隔离的聚合根。 没有导航属性到其他聚合。

  2. 您的存储库更像是一个查询容器,其中包含您的域所需的查询。

  3. Nr#1更加孤立,如果您没有O / R Mapper,它可以很好地工作,您可以简单地构建聚合并返回聚合的死列表。

    如果使用O / R Mapper,

    Nr#2是一种更实用的方法。 这是因为 1)O / R映射器可以处理导航属性和对象的整个图形。 2)一些映射器,例如当您“添加”到存储库时,实体框架将附加新对象的整个图形。 例如假设您一起创建订单,订单详细信息和产品,并且您致电.Add(order).Save(order),EF将附加所有三个实体。也就是说,如果细节指向它,也会保存产品。

    因此,如果您使用O / R映射器,我会选择方法#2 ..

    并且还要注意,这与DDD很少有关,DDD是关于语义和模型的,而不是关于你的基础设施是如何设计的。

答案 1 :(得分:0)

如果问题实体具有外键UserID字段&关系设置为用户实体,可以与用户一起提取问题。

答案 2 :(得分:0)

如果您使用的是EF5和Linq 你可以编写linq查询来获取两个

答案 3 :(得分:0)

如果确实QuestionUser位于两个不同的BC中,那么您可能会发现User BC中的Question实际上是其他内容,例如QuestionOwner 。当然,我是出于说明目的而编写这个术语。 :)

AR永远不应该包含另一个AR的实例,因此无论它们是否在同一个BC中,包含 AR(在这种情况下为User)都应该由一个 Id ,或者更合适的是一个VO。让我们使用QuestionOwner,其中包含存储在UserId中的UserNameQuestion

通过这种方式,Question BC消耗了一些User BC数据,并以Question BC中有意义的形式表示数据。请记住,由于VO是不可变的,因此您不会管理QuestionOwner BC中的任何Question数据,即使User BC中相应的User数据发生更改,您也会添加代表User数据的好处,就像创建问题时那样。根据您的使用情况,您将根据这些设计决定做出这些决定。您还可以选择在用户数据更改时使用某些事件框架(服务总线)更新Question'所有者'。