代码之家  ›  专栏  ›  技术社区  ›  Seb

DDD只读存储库返回“值对象”

  •  6
  • Seb  · 技术社区  · 7 年前

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

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

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

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

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

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

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

    3 回复  |  直到 7 年前
        1
  •  7
  •   VoiceOfUnreason    3 年前

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

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

    埃里克·埃文斯第一次描述 ,他一直在从事一项设计,其中“聚合”接口用于读写。因此,您将有一个单一的存储库,它将为应用程序提供根实体。

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

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

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

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

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

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

        2
  •  4
  •   poul_ko    7 年前

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

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

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

        3
  •  0
  •   EasterBunnyBugSmasher    7 年前

    只是因为你的

    用于连接/处理从各种表中提取的数据的函数

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