为什么数据传输对象(DTO)是反模式?

我最近听到有人说数据传输对象 (DTO)是反模式的

为什么? 有什么select?

有些项目有两次所有的数据 。 一次作为域对象,一次作为数据传输对象。

这种重复的成本很高 ,所以架构需要从这个分离中获得巨大的收益。

DTO不是反模式。 当你通过线路发送一些数据(比如说,通过Ajax调用发送到一个网页)时,你需要确保只发送目的地将要使用的数据来节省带宽。 而且,对于表示层来说,数据的格式通常与本地业务对象的格式略有不同,

我知道这是一个面向Java的问题,但在.NET语言中,匿名types,序列化和LINQ允许dynamic构buildDTO,从而减less了使用它们的设置和开销。

DTO EJB 3.0中的AntiPattern说:

在EJB 3.0之前的EJB规范中,Entity Beans的重量特性导致了像数据传输对象(DTO)这样的devise模式的使用。 DTO成为轻量级对象(本来应该是实体bean本身),用于跨层发送数据…现在,EJB 3.0规范使得实体bean模型与普通旧Java对象(PO​​JO)相同。 使用这个新的POJO模型,您将不再需要为每个实体或一组实体创build一个DTO …如果要跨层发送EJB 3.0实体,只需实现java.io.Serialiazable

我不认为DTO本身就是一种反模式,但是有一些反模式与使用DTO有关。 比尔·杜德尼(Bill Dudney)提到DTO爆炸就是一个例子:

2003/speakers/DudneyJ2EEAntiPatterns.pdf

在这里提到的DTO也有一些滥用:

http://anirudhvyas.com/root/2008/04/19/abuses-of-dto-pattern-in-java-world/

他们起源于三层系统(通常使用EJB作为技术)作为在层之间传递数据的手段。 大多数基于Spring等框架的现代Java系统采用POJO作为域对象(通常用JPA注释等)在单层中的替代简化视图…在这里使用DTO是没有必要的。

OO纯粹主义者会说DTO是反模式的,因为对象变成了数据表格而不是真实的域对象。

有些人认为DTO可能是滥用的反模​​式。 当他们不应该/不需要时,他们经常被使用。

这篇文章模糊地描述了一些虐待。

如果你正在build立一个分布式系统,那么DTO肯定不是反模式。 不是每个人都会从这个意义上来开发,但是如果你有一个(例如)开放社交应用程序都运行JavaScript。

它会发布一个数据加载到您的API。 然后将其反序列化为某种forms的对象,通常是DTO / Request对象。 这可以进行validation,以确保input的数据在转换为模型对象之前是正确的。

在我看来,它被视为反模式,因为它被误用了。 如果你没有build立一个分布式系统,你可能不需要它们。

数据传输对象的目的是存储来自不同来源的数据,然后将其一次传输到数据库(或远程门面 )。

但是, DTO模式违反了单一职责原则 ,因为DTO不仅存储数据,而且还将数据从数据库/外观转移到数据库/外观。

从业务对象中分离数据对象的需求不是反模式,因为它可能需要分离数据库层 。

您应该使用聚合和存储库模式(而不是DTO)来分离对象( 聚合 )和数据传输( 存储库 )的集合 。

要传输一组对象,可以使用Unit Of Work模式,它包含一组存储库和一个事务上下文; 以便在交易中分别转移汇总中的每个对象。

DTO成为一个必要的,而不是一个反模式,当你所有的域对象加载相关的对象EAGERly。

如果您不制作DTO,则您的业务层中会有不必要的传输对象到您的客户端/ Web层。

为了限制这种情况的开销,而是转移DTO。

我认为人们的意思是,如果你把所有的远程对象都作为DTO来实现的话,这可能是一种反模式。 一个DTO只是一组属性,如果你有大对象,即使你不需要或使用它们,也总是可以传输所有的属性。 在后一种情况下,更喜欢使用代理模式。