【问题标题】:DDD Read-Only Repositories returning "value objects"DDD 只读存储库返回“值对象”
【发布时间】:2017-12-19 02:14:34
【问题描述】:

我正在构建一个小型定价引擎,但为了组织业务逻辑,我正在尝试遵循 DDD 概念。

我正面临一个有趣的情况。为了简化我的代码,我依靠 db 函数来连接/处理从各种表中提取的数据。例如,我有一个函数可以计算“中心”的每日时间表。此函数的输出不是真正的实体(没有真实 ID),并且关联的存储库不支持创建/更新/删除功能。

同样,我使用一个函数来计算基本资源定价(列出资源,检查每个时间范围的价格......)。

最后,我感觉我的存储库正在返回值对象。

据我所知,存储库应该返回聚合,它们本身包含实体。

那么如何返回数据库中计算出来的“数据”/值对象呢?

感谢您的帮助, 塞巴斯蒂安

【问题讨论】:

    标签: design-patterns domain-driven-design


    【解决方案1】:

    最后,我感觉我的存储库正在返回值对象。

    这对于只读用例完全有意义。

    当 Eric Evans 首次描述 时,他一直在从事一种将“聚合”接口用于读取和写入的设计。因此,您将拥有一个存储库,该存储库将为应用程序提供根实体。

    然而,几年后,格雷格·杨发表了一次演讲,提出了一种不同的模式;读取职责和写入职责分为两个对象。对于处理写入的用例,实体仍然有意义。

    但对于读取,您并没有尝试更改身份到状态的映射。因此,您可以通过简单地返回当前状态的副本来支持该用例,即

    因此,您将拥有一个支持写入的存储库,以及一个或多个支持读取的附加存储库。

    如今,这种模式被称为命令查询职责分离,或

    就实际实现而言,它完全符合您的预期。支持读取用例的存储库接口返回值对象(内部状态不可变的对象)。

    在某些情况下,让存储库只返回一个表示是有意义的。例如,如果您的“应用程序”是需要返回 JSON 文本的 Web API,那么您可以让存储库直接返回对象的 json 表示,而不是从域模型中获取的“值对象”。

    【讨论】:

    • 当你说“CQRS”时,你的意思是我应该用一个查询+一个直接访问 DbContext 的处理程序替换我的实际存储库吗?这样我就会有一个服务“提出”一个查询。我会将我的数组作为输出并继续该过程
    • 查询将在域项目和基础设施层的处理程序中。还有
    【解决方案2】:

    从存储库返回值对象或其他非实体数据本身并不是一件坏事。例如,当您需要计算所有客户端时,您不应从 repo 中获取所有客户端实体,repo 应提供返回整数(值对象)的方法。

    但在你的情况下,我想你错过了一些领域概念。看起来您将域逻辑移到了 DAL 中。如果是真的,请三思。

    考虑将逻辑放入业务层。在某个时间点,业务代码应该加载所有数据,进行计算(检查价格)并使用 repo 存储现成的数据。就像您在 BL 中执行连接一样。

    【讨论】:

      【解决方案3】:

      只是因为你的

      连接/处理从各种表中提取的数据的功能

      在数据库中运行不会自动使其成为存储库。对我来说,它看起来像是一个返回值对象的服务。您的数据库函数本身可以依赖于类似于存储库的其他函数/构造。

      【讨论】:

        猜你喜欢
        • 2017-03-17
        • 2017-06-27
        • 2011-03-24
        • 2019-10-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多