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

时间:2017-12-19 02:14:34

标签: design-patterns domain-driven-design

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

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

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

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

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

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

谢谢你的帮助, 的Sebastien

3 个答案:

答案 0 :(得分:2)

  

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

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

当埃里克埃文斯第一次描述时,他一直在设计一个"""聚合接口用于读取和写入。因此,您将拥有一个存储库,它将为应用程序提供根实体。

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

但是对于读取,你并没有试图改变身份到状态的映射。因此,您只需返回当前状态的副本即即可支持该用例。

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

目前,该模式称为命令查询责任隔离,或

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

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

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:0)

只是因为你的

  

用于加入/处理从各种表中提取的数据的功能

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