使用DTO(数据传输对象)有什么意义?


132

使用DTO的意义何在?它是过时的概念吗?我在视图层中使用POJO来传输和保留数据。可以将这些POJO视为DTO的替代方法吗?


10
但是POJO可以是DTO,DTO可以用POJO来实现。你是比较苹果和桔子。
欣快的2012年

3
为什么好主意会过时?看一下Lisp。除了笑话,我同意欣快感:我通常使用POJO实现DTO。我仍然发现DTO非常简单(KISS)和有用的概念。
乔治

没有意义,这是一种反模式,请参阅:数据传输对象是一种耻辱
yegor256 '16

Answers:


115

DTO是一种模式,它独立于实现(POJO / POCO)。DTO说,由于对任何远程接口的每次调用都是昂贵的,因此对每个调用的响应应带来尽可能多的数据。因此,如果需要多个请求来携带特定任务的数据,则可以将要携带的数据合并到DTO中,以便只有一个请求可以携带所有必需的数据。企业应用程序体系结构模式目录有更多详细信息。

DTO是一个基本概念,并非过时。


9
您可能会发现它们的名称不同,因为这些天所有人似乎都在重新发明轮子
linkerro 2012年

3
就像“值对象”。
theD 2012年

2
@linkerro:正确:我认为许多人应该花更多的时间阅读已经发明的东西,而不是自己重新发明。重新发明的东西永远不会那么成熟。
乔治

10
@Giorgio那里还有很多开发人员,他们的想法本来应该从未实现过。我希望更多的开发人员对他们阅读的每个想法提出质疑。
Erik Reppen 2013年

59

DTO作为一个概念(目的是收集要由服务器返回给客户端的数据的对象)当然不是过时的。

什么有些过时是具有不包含逻辑在所有的DTO的概念中,使用用于发送数据和从域对象“映射”传输之前给客户端,并且有映射它们传递给显示层之前查看模型。在简单的应用程序中,域对象通常可以直接用作DTO,并直接传递到显示层,因此只有一个统一的数据模型。对于更复杂的应用程序,您不想将整个域模型公开给客户端,因此从域模型到DTO的映射是必需的。拥有一个单独的视图模型来复制来自DTO的数据几乎是没有意义的。

但是,此概念过时而不是简单错误的原因是某些(主要是较旧的)框架/技术需要它,因为它们的域和视图模型不是POJOS,而是直接与框架绑定。

最值得注意的是,EJB 3标准之前的J2EE中的Entity Bean不是POJO,而是由应用服务器构造的代理对象-根本不可能将它们发送给客户端,因此您没有选择拥有单独的DTO层-这是强制性的。


2
当UI开发人员被迫担任更一般的角色时,我肯定在我们的代码库中发现了Mapper.Map现象。为什么DTO不能自己映射?
Erik Reppen 2013年

1
@ErikReppen的主要好处是将您的域模型与DTO分离。如果您的DTO自己映射,则需要引用您的域模型。
亚历山大·德克

17

尽管DTO并不是一种过时的模式,但通常会不必要地应用它,这可能会使它显得过时。

Java Enterprise社区中最被滥用的模式是DTO。DTO被明确定义为分配问题的解决方案。DTO旨在成为一种粗粒度的数据容器,可以在流程(层)之间有效地传输数据。〜亚当·比恩

例如,假设您有一个JSF ManagedBean。一个常见的问题是,bean是应该直接持有对JPA实体的引用,还是应该维护对某些中间对象的引用,该对象随后将转换为Entity。我听说过这个称为DTO的中间对象,但是如果您的ManagedBeans和Entities在同一个JVM中运行,那么使用DTO模式几乎没有好处。

考虑Bean验证注释。您的JPA实体可能使用@NotNull和@Size验证进行注释。如果您使用的是DTO,则需要在DTO中重复这些验证,以便使用远程接口的客户端无需发送消息即可发现其基本验证失败。想象一下在DTO和实体之间复制Bean验证批注的所有额外工作,但是如果您的视图和实体在同一JVM中运行,则无需进行这项额外工作:只需使用实体。

IAmTheDude到企业应用程序体系结构模式目录的链接提供了DTO的简要说明,下面是我发现的更多参考:


3
有一句话:“ ...,但是,如果您的ManagedBeans和Entities在同一个JVM中运行,那么使用DTO模式几乎没有好处”。公司中有许多中型应用程序愚蠢地实施了DTO模式,却没有任何好处。它只是添加了一个无用的“复制层”。创建这些系统的人员没有意识到Java EE 5+实体管理器在事务结束时将实体分离并使其成为实际的DTO。因此,对于单JVM Web应用程序,这种模式已经过时了。似乎是J2EE后端开发人员的遗物...
Kawu

但是什么是“ JSF ManagedBean”和“ JPA实体”?如果它们不是过时的,那么您应该能够使用与框架和语言无关的术语来解释它们。
阿瓦洛斯

8

绝对不!最近,我吸取了关于更好地使用DTO而不是使用您的业务对象(可能绑定到ORM映射器)的经验教训

但是,仅在适合使用它们时才使用它们,而不仅仅是为了使用它们,因为它们在一些好的模式书中都有提及。
我想到的一个典型示例是当您向第三方公开某种界面时。在这种情况下,您希望保持交换对象相当稳定,通常可以使用DTO很好地实现它们。


1

我发现DTO尤其有用的一个地方是包含API响应的逻辑。通过这种模式,可以以可测试的方式轻松管理从对象到各种格式的不同类型的响应。在我目前的职位上使用此模式,我们能够开始测试API的响应格式,这很有价值,因为我们的堆栈在各种客户端(http / mobile)下变得更加同构。绝对不会过时。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.