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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1440952/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 12:18:46  来源:igfitidea点击:

Why are data transfer objects (DTOs) an anti-pattern?

javaejbdtoanti-patternsdata-transfer-objects

提问by ntownsend

I've recently overheard people saying that data transfer objects(DTOs) are an anti-pattern.

我最近无意中听到有人说数据传输对象(DTO) 是一种反模式

Why? What are the alternatives?

为什么?有哪些替代方案?

采纳答案by KLE

Some projects have all data twice. Once as domain objects, and once as data transfer objects.

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

This duplication has a huge cost, so the architecture needs to get a huge benefit from this separation to be worth it.

这种重复具有巨大的成本,因此架构需要从这种分离中获得巨大的好处才值得。

回答by Darin Dimitrov

OO purists would say that DTO is anti-pattern because objects become data table representations instead of real domain objects.

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

回答by jdehaan

I think the people mean it could be an anti-pattern if you implement all remote objects as DTOs. A DTO is merely just a set of attributes and if you have big objects you would always transfer all the attributes even if you do not need or use them. In the latter case prefer using a Proxy pattern.

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

回答by Ben S

Some consider DTOs an anti-pattern due to their possible abuses. They're often used when they shouldn't be/don't need to be.

有些人认为 DTO 是一种反模式,因为它们可能被滥用。它们经常在不应该/不需要的时候使用。

This articlevaguely describes some abuses.

这篇文章模糊地描述了一些滥用行为。

回答by aem

DTO an AntiPattern in EJB 3.0says:

EJB 3.0 中的反模式 DTO说:

The heavy weight nature of Entity Beans in EJB specifications prior to EJB 3.0, resulted in the usage of design patterns like Data Transfer Objects (DTO). DTOs became the lightweight objects (which should have been the entity beans themselves in the first place), used for sending the data across the tiers... now EJB 3.0 spec makes the Entity bean model same as Plain old Java object (POJO). With this new POJO model, you will no longer need to create a DTO for each entity or for a set of entities... If you want to send the EJB 3.0 entities across the tier make them just implement java.io.Serialiazable

EJB 3.0 之前的 EJB 规范中实体 Bean 的重量级性质导致使用数据传输对象 (DTO) 等设计模式。DTO 成为轻量级对象(首先应该是实体 bean 本身),用于跨层发送数据……现在 EJB 3.0 规范使实体 bean 模型与普通旧 Java 对象 (POJO) 相同。使用这个新的 POJO 模型,您将不再需要为每个实体或一组实体创建一个 DTO...如果您想跨层发送 EJB 3.0 实体,让它们只实现 java.io.Serialiazable

回答by Jon

I don't think DTOs are an anti-pattern per se, but there are antipatterns associated with the use of DTOs. Bill Dudney refers to DTO explosion as an example:

我不认为 DTO 本身是一种反模式,但存在与使用 DTO 相关的反模式。Bill Dudney 以 DTO 爆炸为例:

http://www.softwaresummit.com/2003/speakers/DudneyJ2EEAntiPatterns.pdf

http://www.softwaresummit.com/2003/speakers/DudneyJ2EEAntiPatterns.pdf

There are also a number of abuses of DTOs mentioned here:

这里还提到了一些 DTO 的滥用:

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

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

They originated because of three tier systems (typically using EJB as technology) as a means to pass data between tiers. Most modern day Java systems based on frameworks such as Spring take a alternative simplified view using POJOs as domain objects (often annotated with JPA etc...) in a single tier... The use of DTOs here is unnecessary.

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

回答by Gabe Moothart

DTOs are not an anti-pattern. When you're sending some data across the wire (say, to an web page in an Ajax call), you want to be sure that you conserve bandwidth by only sending data that the destination will use. Also, often it is convenient for the presentation layer to have the data in a slightly different format than a native business object.

DTO 不是反模式。当您通过网络发送一些数据时(例如,在 Ajax 调用中发送到网页),您希望通过仅发送目标将使用的数据来确保节省带宽。此外,对于表示层来说,使用与本机业务对象略有不同的格式的数据通常很方便。

I know this is a Java-oriented question, but in .NET languages anonymous types, serialization, and LINQ allow DTOs to be constructed on-the-fly, which reduces the setup and overhead of using them.

我知道这是一个面向 Java 的问题,但在 .NET 语言中,匿名类型、序列化和 LINQ 允许动态构建 DTO,这减少了使用它们的设置和开销。

回答by Bealer

If you're building a distributed system, then DTOs are certainly not an anti pattern. Not everyone will develop in that sense, but if you have a (for example) Open Social app all running off JavaScript.

如果您正在构建分布式系统,那么 DTO 肯定不是一种反模式。不是每个人都会在这个意义上进行开发,但如果你有一个(例如)Open Social 应用程序全部运行 JavaScript。

It will post a load of data to your API. This is then deserialized into some form of object, typically a DTO/Request object. This can then be validated to ensure the data entered is correct before being converted into a model object.

它会将大量数据发布到您的 API。然后将其反序列化为某种形式的对象,通常是 DTO/Request 对象。然后可以对其进行验证,以确保在转换为模型对象之前输入的数据是正确的。

In my opinion, it's seen as an anti-pattern because it's mis-used. If you're not build a distributed system, chances are you don't need them.

在我看来,它被视为一种反模式,因为它被误用了。如果您不构建分布式系统,则您可能不需要它们。

回答by MovGP0

The intention of a Data Transfer Objectis to store data from different sources and then transfer it into a database (or Remote Facade) at once.

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

However, the DTO pattern violates the Single Responsibility Principle, since the DTO not only stores data, but also transfers it from or to the database/facade.

然而,DTO 模式违反了单一职责原则,因为 DTO 不仅存储数据,而且还从或向数据库/外观传输数据。

The need to separate data objects from business objects is not an antipattern, since it is probably required to separate the database layeranyway.

将数据对象与业务对象分开的需要并不是一种反模式,因为无论如何都可能需要将数据库层分开

Instead of DTOs you should use the Aggregate and Repository Patterns, which separates the collection of objects (Aggregate) and the data transfer (Repository).

您应该使用聚合和存储库模式而不是 DTO,它将对象集合 ( Aggregate) 和数据传输 ( Repository)分开。

To transfer a group of objects you can use the Unit Of Workpattern, that holds a set of Repositories and a transaction context; in order to transfer each object in the aggregate separately within the transaction.

要传输一组对象,您可以使用工作单元模式,它包含一组存储库和一个事务上下文;以便在交易中分别传输聚合中的每个对象。

回答by javadev

DTO becomes a necessity and not an ANTI-PATTERN when you have all your domain objects load associated objects EAGERly.

当您让所有域对象都急切地加载关联对象时,DTO 成为必需品而不是反模式。

If you don't make DTOs, you will have unnecessary transferred objects from your business layer to your client/web layer.

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

To limit overhead for this case, rather transfer DTOs.

为了限制这种情况下的开销,不如转移 DTO。