【问题标题】:In DDD, how do you work with multiple repositories for read-only lists在 DDD 中,如何使用多个存储库获取只读列表
【发布时间】:2010-03-23 15:03:41
【问题描述】:

如果您需要在页面上生成只读数据列表,并且该数据自然会来自多个(可能是 5 个或更多)不同的存储库,您会怎么做?

我们正在使用 DDD,并且一直在强制通过存储库访问我们的数据库,但是出现了一个似乎不适合 DDD 的场景,我们正在尝试确定要使用的最佳模式。

例如,假设您有一个基于社区的网站,其中包含视频、论坛、博客等。您有一个包含 cmets 列表的论坛页面。这很粗略,但我希望它有意义。

<table>
<tr><td>User Name (with possible link)</td><td>User's community score.</td><td>User Avatar</td><td>User's E-mail</td><td>User's blog</td><td>User's videos</td></tr>
</table>
<table>
<tr><td>This is a comment.</td></tr>
</table>

因此,每条评论都包含几个不同的部分:用户名、社区分数、头像、电子邮件、用户的博客和用户的视频页面。传统上,这些信息都来自不同的存储库。

问题在于效率。存储库可以最大化,但只能围绕为其创建的聚合。当您需要访问位于多个存储库中的数据时,使用存储库对读取访问变得低效。

我的解决方案是使用相关信息创建一个 UserInformation DTO,并在 UserForumsRepository 中放置一个带有签名的方法

ILIst<UserInformation> GetUserForumsUserInformationByForumPostID(int forumPostID).

我的一位同事建议以这种方式使用 DTO 会破坏我们一直在使用的设计模式,并建议更好的方法是获取论坛评论 ID 列表,然后将这些 ID 传递到各个存储库返回结果。

我自己的观点是,存储库的主要目的是封装对 CRUD 的 CUD 部分很重要的业务逻辑,但只读列表应该以最有意义的方式生成。如果合适的话,我认为从存储库中完全删除只读列表方法甚至是有意义的(例如,在跨多个不同类型页面使用的通用小部件中)。

你如何处理这种情况?

【问题讨论】:

    标签: repository domain-driven-design dto


    【解决方案1】:

    我讨厌回答我自己的问题,但我没有任何 cmets,而且我似乎从通常的嫌疑人那里找到了答案:Fowler。

    在我们的设计中,与大多数简单的 DDD 相同,我们的应用程序直接连接到我们的存储库以获取和更新数据。但是,在更复杂的场景中,在具体存储库和应用程序层之间还有一个额外的服务层。您无需将对象从域模型传递给客户端,而是传递 DTO。

    根据 Fower (PoEAA 401),您“...通常不能从域模型中传输对象,...因为对象通常连接在一个复杂的网络中,即使不是不可能,也很难序列化。 " Fowler 继续说:“相反,您必须从域对象中传输简化形式的数据。”

    实际上,尤其是在分布式系统中,将 DTO 传递给客户端是常态。服务层如何从域层组装这些 DTO 应该是客户端不感兴趣的。

    我必须承认,Fowler 的这句话让我有些苦恼。 我非常喜欢在 ASP.Net MVC 中使用域模型的便利性。它在创建主从 UI 设计模式视图时特别方便。当强类型视图与客户相关联时,只需一行代码即可包含 CustomerOrders.ascx 部分视图(类型为 IList)并将 customer.Orders 传递给部分视图。也许继续这样做是可以的,只要域对象没有行为,但这是一个未来的问题。

    【讨论】:

    • 无行为域模型是一种称为贫血域模型的反模式。我们使用 dto 来解决您遇到的问题。一个或多个存储库被组合以将多个实体映射到一个扁平化的 dto,然后将其发送到客户端。如果您将实体发送给客户端,则会冒着您的域模型的状态以不一致的方式发生变化的风险。
    • 您是在服务层还是在存储库层这样做?
    【解决方案2】:

    答案 #2

    这里需要的是具体存储库和客户端之间的额外服务层。有时,客户端需要的与存储库层提供的不同,尤其是在存储库可能是分布式的情况下。服务层允许您定义粗粒度的方法并向客户端隐藏细粒度的细节。通过服务层,您可以将轻量级 DTO 传递给客户端,而不是完整的业务对象。

    为了将业务对象映射到 DTO 或反之,Automapper 工具变得非常流行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-30
      • 2011-01-17
      • 2021-11-26
      相关资源
      最近更新 更多