为什么存储库不应该返回 DTO

Pau*_*all 1 php design-patterns laravel

阅读很多文章,人们说我应该返回域模型……但这会破坏我的存储库的整个想法。

我正在使用 laravel Eloquent 模型(如果我是对的 - 域模型)。我有存储库,所以如果我决定切换到 Doctrine,我可以在服务提供商处将其全部交换。但是如果我将返回一个没有意义的域模型(在本例中为 Eloquent 模型)的实例。我需要从存储库返回相同的结果,而 DTO 似乎正是我所需要的......

有人可以解释我为什么我错了吗?

Ptr*_*Ton 8

什么是什么

首先,我想对您使用的术语进行解释。

DTO(数据传输对象)

  • 通常是具有公共属性的 PHP 类
  • 只负责携带数据
  • 不不验证数据
  • 不知道任何特定于实现的东西(例如它绑定到哪个 ORM)
  • 通常用于在应用程序的各个部分之间传递数据,而任一部分都不知道另一部分的实现

领域模型

  • 通常是具有私有属性的 PHP 类
  • 应该只包含有效数据
  • 验证任何更改都会导致有效状态
  • 不知道任何特定于实现的东西(例如它绑定到哪个 ORM)

存储库

  • 只负责存储和检索数据
  • 知道它的实现(例如它绑定到哪个 ORM)
  • 不负责返回有效数据

这对您的情况意味着什么

答案实际上取决于您想在分担责任方面考虑的纯粹程度。

如果您与纯粹主义者交谈,他们会说 Eloquent 模型不是 DTO,也不是领域模型。存储库将返回一个 eloquent 模型,该模型将映射到域模型。然后可以修改该域模型或将其转换为可用于读取数据的 DTO。在这种情况下,职责是分开的,代价是拥有更多的代码。

如果您与实用主义者交谈,他们会说 Eloquent 模型是 DTO 和领域模型(有时甚至是存储库)。由于 eloquent 模型负责存储数据、检索数据、修改数据并将这些数据传递给应用程序的其他部分。

归根结底,一切都与偏好有关。你可以变得纯粹,你可以变得务实,你甚至可以在两者之间选择一些东西。这完全取决于您的编码人员有多先进,项目有多大,它应该有多可维护,必须进行多快的更改等。

拖拉机

存储库可以返回 DTO 或域模型,具体取决于您在分离职责方面的想法。

  • 您所描述的域模型在技术上只是一个实体。领域模型通常指一组互连的对象,它们构成了整个领域的数据和业务行为。比照。https://martinfowler.com/eaaCatalog/domainModel.html (3认同)