【问题标题】:Service layer with Data Transfer Objects (DTO)具有数据传输对象 (DTO) 的服务层
【发布时间】:2021-11-15 19:11:05
【问题描述】:

我正在开发基于以下模块的多模块 maven 应用程序:

  1. 模型,包含所有域实体
  2. 持久性,包含用于访问模型的所有存储库(或 DAO)
  3. 服务,包含所有业务逻辑
  4. Web,包含所有控制器逻辑以公开 REST API

我要解决的问题是关于 DTO 映射,现在依赖关系以线性方式组织:

  Model <- Persistence <- Service <- Web

所有 DTO 逻辑应该属于哪里?假设我们在 服务层 中有一个名为

的方法
createRoom(CreateRoomDTO createRoomDTO)

在这种情况下,CreateRoomDTO 类与服务和 Web 模块高度耦合,但并非所有 DTO 类都被服务层使用(例如 PaginationFilter)

【问题讨论】:

  • 一般来说,您可以使用 DTO 与外部世界进行交互。 IE。 - 您可以接受 dto 作为用户界面的输入,或将一些数据传递给另一个服务或将数据存储在数据库中。与外部世界接触的每一层,都必须在 DTO 你的内部模型之间进行转换。您可以为此类转换创建特殊映射器。在哪里打电话给那些映射器?在与外部世界接触的层中。
  • 只是指出域模型/实体(理想情况下)应该与服务类一起,并且实际上包含大部分业务逻辑。您可能想重新访问依赖关系,理想情况下它是persistance -&gt; domain model &lt;- Web,所以一切都取决于逻辑的核心。
  • 哪一层拥有 DTO 定义? createRoom 返回什么?哪个层拥有它?
  • @rascio 通常我将我的 DTO 放在 web 层中,但在这种情况下,问题是我有一些 DTO 应该在两个层中,而其他的应该只在一层但使用从另一个。例如 CreateRoomDTO 保留在 Service 内部,但也用于控制器内部的 Web 层以解析输入
  • @tym32167 所以在这种情况下,我应该在 Web 层内有一个映射器,该映射器将 Web 层 DTO 作为输入并将其映射到服务层 DTO(或者更好地说是命令)

标签: java design-patterns domain-driven-design


【解决方案1】:

这是基于意见的边界,但在我看来,DTO 类应该在服务层和 Web 层之间使用,并且显然是通过您的外部 API 公开数据。原因是如果您只将它们保留在 Web 层中,则意味着您需要将逻辑从服务层推送到 Web 层,以便从 CreateRoomDTO 对象创建域模型。你绝对应该避免它,因为这是应该保留在服务层中的逻辑。

【讨论】:

  • 感谢您的回复,所以在这种情况下,所有 DTO 逻辑都应该留在服务层中,而 Web 层依赖并使用它们?
  • 是的,至少我通常是这样做的。
猜你喜欢
  • 2013-05-27
  • 2010-11-06
  • 2011-03-14
  • 1970-01-01
  • 2011-07-01
  • 2013-03-12
  • 1970-01-01
  • 2012-11-01
  • 2019-08-08
相关资源
最近更新 更多