DDD - 每个实体的存储库还是一个存储库?

时间:2012-02-20 11:51:30

标签: architecture domain-driven-design

首先,可能没有正确答案,但我确信有些人比我更了解并且能够提供帮助。

我有3个实体:用户,博客,帖子。

系统可以有任意数量的用户。

用户可以拥有任意数量的博客,但每个博客只有一个用户。

博客可以拥有与用户发布的帖子一样多的帖子,所有帖子都来自拥有博客的同一用户(即如果John拥有博客Food,只有John可以在此博客中发帖)。当然,每篇文章都有一个家长博客。

然后我有了用户个人资料页面,我想要显示所有用户详细信息,所有博客的名称以及最近5个帖子。

然后我有一个博客页面,显示博客的详细信息,所有者的姓名(用户)和所有帖子的标题。

然后我有一个帖子页面,显示帖子详细信息,博客名称和所有者名称。

如你所见,我所有人之间都有关系,但没有一个可以作为聚合。

在代码中定义实体并不困难,我所遇到的问题是定义存储库。我需要多少钱? 3 - 每个实体一个? 1 - 什么都有?我该如何进行查找?

例如,获取用户页面中的最后5个帖子。用户没有引用帖子,而是拥有博客容器,其中每个博客依次拥有帖子的容器。我的存储库中是否应该接受UserID并返回帖子列表?或者也许应该是服务?此外,我通常不会执行所有数据的加载,而是我有延迟加载。通过检索现有的用户实体,除非需要(首次访问时),否则我不会加载其博客。

提前致谢。

3 个答案:

答案 0 :(得分:4)

我会创建:

  • 用于处理帖子和评论的PostRepository
  • BlogRepository主要用于搜索
  • UserRepository

如果您不支持评论,我会删除帖子库并处理BlogRepository

中的帖子

我通常在使用它们后对存储库进行建模,并避免聚合嵌套(超过两个级别)。

  

例如,获取用户页面中的最后5个帖子。用户没有引用帖子,而是拥有博客容器,其中每个博客依次拥有帖子的容器。

imho用户不应该有Blog的容器。你有存储库来获取它。

  

我的存储库中是否有一个接受UserID并返回帖子列表的方法?

  

或者也许应该是服务?

服务用于从使用域模型的代码中删除业务逻辑。在得到那种逻辑之前不要创建它们。

  

此外,我通常不会执行所有数据的加载,而是我有延迟加载。通过检索现有的用户实体,除非需要(首次访问时),否则我不会加载其博客。

通过不具有将所有域模型链接在一起的属性,可以避免延迟加载。尽量只拥有子聚合的属性。

答案 1 :(得分:1)

在决定是否拥有存储库之前,我会考虑您的实体的重要性。

从测试驱动开发方面来看,我会为每个实体建立一个存储库。这样我可以使用IUserRepository,IBlogPostRepository等虚假实现。这种方法可以促进单元测试,并允许我用另一个实现存储库替换。

然后,我会将我的存储库分组到我觉得合适的服务中。这样做的一种方法是以适合您要求的方式编写用例和组。

例如,我可以说用户可以执行以下操作:

  1. 查看帖子
  2. 提交帖子
  3. 编辑帖子
  4. 我现在可以制作一个IUserService来查看,提交和编辑帖子。该服务将聚合(分组)我的存储库。

    最后,我将能够做到以下几点。

    var blogPost = new BlogPost();
    ServiceFactory.Resolve<IUserService>(c => c.SubmitPost(blogPost));
    

    现在,这是实现此目的的一种方式。

    或者,您可能有一个IBlogPostService会暴露非常相似的行为,或者您只能使用存储库而不实现聚合服务。

    我想说的是,你不应该依赖于细节。通常有多种方法可以实现类似的行为,而你学习的唯一方法就是练习。

    让您的存储库可以重复使用,但问问自己是否过度设计了某些东西,即我是否会单独使用此存储库?一旦您拥有很少的存储库,请将它们包装在聚合服务中。

    如果您的服务有超过3个(阈值完全取决于您)的存储库,那么请考虑将此服务重构为两个单独的服务。

    我希望这会有所帮助。

答案 2 :(得分:0)

用户通常是典型的聚合根。用户聚合可能包含用户首选项,用户统计信息,甚至可能包含博客。

我也看到Post作为聚合根的一个很好的候选者,有很多东西都围绕着它:评论,标签,类别......然后你可以使用PostRepository.LoadByBlog()或PostRepository.LoadByUser()为你的页面

现在这只是你所描述的一种可能性。每个域都是独一无二的,您可能会有我们不知道的游戏更改信息。