繁体   English   中英

数据传输对象DTO在何处构建

[英]Data Transfer Object DTO Where to build

试图重构一些代码。 我看到一些创建DTO对象的类正在服务层中传递,后来由@RestController返回。 据我所知,最好只在控制器中构建数据传输对象并将它们传递给视图,尤其是当我们使用带有get和set值的WrapperDTO<T>类的东西时。 当我们使用复杂对象或简单数据类型构建WrapperDTO时,可能存在差异。 所有的oppinions将非常感激。

DTO可用于在应用程序的不同层之间传输数据:DAO,服务,外观,控制器。 根据我的经验,DTO是一个自以为是的主题。

在我看来,转换越晚越好,如果不需要转换则更好。 通常,后者位于应用程序边界。 DTO不是免费的,它涉及映射及其支持。 因此,当存在域模型不匹配或模型技术不匹配时,DTO将是有意义的。 有关更多信息,您可以查看LocalDTO文章和相关链接

如果我专注于服务 - > facade - > 控制器层:

  • 服务:他们正在做服务,他们可能会互相打电话进行处理。 如果您的域模型在服务边界service => facade保持一致,那么将结果转换为DTO为时尚早。

  • Facades:他们可以协调服务并转换输入/输出。 在我看来,它将是转换到DTO或从DTO转换的正确位置。 但只有在需要时才是这样。 因为你的域模型必须在这个边界上进行转换(过滤字段,聚合......)

  • 网关/控制器:它们位于应用程序边界。 他们的逻辑很简单,简化为边界逻辑。 外观和控制器之间的关系通常是one <-> one ***

    合并外墙和控制器通常是有道理的


因此,在我看来,你的第一个提案更适合,例如。 UserController.... 最重要的是保持务实。

我想说最好在服务层创建DTO。

控制器必须不知道业务逻辑细节。 例如,我们需要返回用户信息,但必须排除某些字段(密码等)。 这些字段存在于用户实体中,但必须从DTO中删除。

另一个案例我们在Controller上获得了SomePaginationDTO ,我们仍然需要将DTO传递给服务来解析过滤器,应用排序,限制结果等。所有逻辑都是服务责任的一部分。 所以我会将SomePaginationDTO传递给服务。

我会说没有规范的正确方法来做到这一点。 这取决于DTO的用途。

我为自己找到了一个简单的规则,即在服务级别使用DTO的位置以及不在何处使用DTO: 如果服务级别只有一个客户端,我在服务级别使用DTO。 如果有两个或更多客户端,最好不要在服务级别使用DTO。

让我更详细地解释一下:

基本上很明显,不将DTO纳入服务水平需要更多的努力。 因此,如果只有一个客户端,我会保持简单,并使用DTO作为服务方法的返回类型。

如果服务的客户端多于一个,则客户端最有可能需要不同的DTO(例如,我想要一个对象的jsoncsv表示)。 在这种情况下,我不会从服务中返回DTO。 否则,我需要为每个DTO或不同的服务方法等提供不同的服务。

注意:我不是说如果你不在服务级别使用DTO,你必须将转换逻辑移动到控制器级别。 我仍然认为控制器级别必须尽可能简单。 您可能在控制器和服务之间有一些中间转换级别 - 不舒服,但它比使用多个服务要好得多。

作为其他问题的一部分,我找到了一个很好的答案。 当然这个/我的答案不参与赏金。 这只是一个解释如何实现事物的灵感。 所以看看:

  • 模型类。 他们没有获得所有东西的吸气剂/安装者。 这取决于模型逻辑。 否则你会得到模型,你很容易打破一致性。 或者许多不明显的事情在哪里。 假设您有User.registrationDate字段。 构造新的User对象时,不要忘记手动注册registrationDate字段。 所以,只需在构造函数中放置registrationDate初始化并删除setter!
  • 存储库接口就在您的模型中。 假设您有一些依赖于现有存储对象的业务逻辑。 您无法明确地将域逻辑引用到基础结构依赖项(如JPA,Hibernate,JDBC等)中。因此,您可以从接口查询此存储的对象。
  • 商业服务(可选)。 它们实现了一些复杂的逻辑,涉及许多不同的实体,不包括安全和事务管理。 你的问题是关于它的。 是的,如果您需要查询域逻辑中的实体,请将查询放入存储库并从业务服务中调用它。
  • 基础架构包内的存储库实现。 使用JPA或mockito或其他任何方式实现存储库接口。 它们也不包括安全性和交易。
  • 应用程序服务(可选)。 如果与基础架构或安全检查存在一些复杂的交互。
  • 远程门面界面。 客户端和服务器仅通过远程外观接口进行通信
  • 远程外观实现(控制器)。 将厚实体对象转换为精简DTO(数据传输对象)。 所有事务划分和安全性都在这里(通常使用注释)。

你怎么看待这个设计? 适用于众所周知的弹簧mvc吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM