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

廉价感情. 提交于 2019-11-26 14:06:01
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.

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.

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.

DTO an AntiPattern in EJB 3.0 says:

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

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:

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

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

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.

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

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.

This article vaguely describes some abuses.

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.

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.

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.

javadev

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

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

To limit overhead for this case, rather transfer DTOs.

The intention of a Data Transfer Object is 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.

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

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

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

The question should not be "why", but "when".

Definitively it's anti-pattern when only result of using it is higher cost - run-time or maintenance. I worked on projects having hundreds of DTOs identical to database entity classes. Each time you wanted to add a single field you ad to add id like four times - to DTO, to entity, to conversion from DTO to domain classes or entities, the inverse conversion, ... You forgot some of the places and data got inconsistent.

It's not anti-pattern when you really need different representation of domain classes - more flat, more rich, more narrow, ...

Personally I start with domain class and pass it around, with proper check in the right places. I can annotate and/or add some "helper" classes to make mappings, to database, to serialization formats like JSON or XML ... I can always split a class to two if I feel the need.

It's about your point of view - I prefer to look at a domain object as a single object playing various roles, instead of multiple objects created from each other. If the only role an object has is transporting data, then it's DTO.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!