Почему объекты передачи данных (DTO) анти-паттерн?

Я недавно подслушал, как люди говорят это объекты передачи данных (DTOs) являются анти-шаблон.

Почему? Каковы альтернативы?

11 ответов


некоторые проекты имеют все данные дважды. Один раз как объекты домена и один раз как объекты передачи данных.

этой дублирование имеет огромную стоимость, поэтому архитектура должна получить огромную выгоду от этого разделения, чтобы оно того стоило.


DTOs не являются анти-шаблоном. Когда вы отправляете некоторые данные по проводам (например, на веб-страницу в вызове Ajax), вы хотите быть уверены, что вы сохраняете пропускную способность, только отправляя данные, которые будет использовать назначение. Кроме того, часто для уровня презентации удобно иметь данные в несколько ином формате, чем собственный бизнес-объект.

Я знаю, что это Java-ориентированный вопрос, но в .NET-языках анонимные типы, сериализация и LINQ позволяют DTOs быть построенный на лету, который уменьшает установку и накладные расходы использования их.


DTO антипаттерн в EJB 3.0 говорит:

тяжеловесная природа сущности Фасоли в спецификациях EJB до EJB 3.0 в результате использования шаблоны проектирования, такие как передача данных Объекты (DTO). Объекты переноса данных стал легкие объекты (которые должны иметь был ли сущность бобы себя в первое место), используется для отправки данные по уровням... теперь в версии EJB 3.0 spec делает модель компонента сущности одинаковой как простой старый объект Java (POJO-объект). С эта новая модель POJO, вы не будете больше нужно создать DTO для каждого сущность или для набора сущностей... Если вы хотите отправить объекты EJB 3.0 по ту сторону яруса сделай их просто реализовать Java.Ио.Serialiazable


Я не думаю, что DTO-это анти-шаблон как таковой, но есть антипаттеры, связанные с использованием DTO. Билл Дадни ссылается на взрыв DTO в качестве примера:

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

есть также ряд злоупотреблений DTO, упомянутых здесь:

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

Они возникли из-за трехуровневых систем (обычно использующих EJB в качестве технологии) в качестве средства передачи данных между уровнями. Большинство современных Java-систем, основанных на таких фреймворках, как Spring, используют альтернативный упрощенный вид, используя POJOs в качестве объектов домена (часто аннотированных JPA и т. д...) в один ярус... Использование DTO здесь не нужно.


OO пуристы сказали бы, что DTO является анти-шаблоном, потому что объекты становятся представлениями таблиц данных вместо реальных объектов домена.


некоторые считают DTOs анти-шаблоном из-за их возможных злоупотреблений. Они часто используются, когда они не должны/не должны быть.

в этой статье смутно описывает некоторые злоупотребления.


Если вы создаете распределенную систему, то DTO, безусловно, не являются анти-шаблоном. Не все будут развиваться в этом смысле, но если у вас есть (например) открытое социальное приложение, все работает с JavaScript.

он разместит загрузку данных в ваш API. Затем это десериализуется в некоторую форму объекта, обычно объект DTO/Request. Затем это можно проверить, чтобы убедиться, что введенные данные верны перед преобразованием в объект модели.

на мой взгляд, это рассматривается как анти-шаблон, потому что он неправильно используется. Если вы не строите распределенную систему, скорее всего, они вам не нужны.


DTO становится необходимостью, а не анти-шаблоном, когда все ваши объекты домена загружают связанные объекты с нетерпением.

Если вы не делаете DTOs, у вас будут ненужные перенесенные объекты с вашего бизнес-уровня на клиентский/веб-уровень.

чтобы ограничить накладные расходы для этого случая, скорее перенесите DTOs.


намерение Объект Передачи Данных - хранить данные из разных источников, а затем передавать ее в базу данных (или Удаленный Фасад) сразу.

, шаблон DTO нарушает Принцип Единой Ответственности, поскольку DTO не только хранит данные, но и передает их из или в базу данных/фасад.

необходимость отделять объекты данных от бизнес-объектов не является антипаттерном, поскольку это, вероятно, требуется отделить слой базы данных в любом случае.

вместо DTOs следует использовать шаблоны Aggregate и Repository, которые разделяют коллекцию объектов (совокупность) и передачи данных (хранилище).

для передачи группы объектов вы можете использовать Единица Работы pattern, который содержит набор репозиториев и контекст транзакции; для передачи каждого объекта в совокупность отдельно в рамках транзакции.


Я думаю, что люди имеют в виду, что это может быть анти-шаблон, если вы реализуете все удаленные объекты как DTO. DTO-это просто набор атрибутов, и если у вас есть большие объекты, вы всегда будете передавать все атрибуты, даже если они вам не нужны или не используются. В последнем случае предпочитают использовать шаблон Proxy.


вопрос должен быть не "почему", а", когда".

определенно анти-шаблон, когда только результат его использования выше стоимость - время выполнения или обслуживания. Я работал над проектами, имеющими сотни DTOs, идентичных классам сущностей базы данных. Каждый раз, когда вы хотите добавить одно поле, вы добавляете id как четыре раза - в DTO, в entity, в преобразование из DTO в доменные классы или сущности, обратное преобразование ... Ты забыл некоторые места. и данные стали непоследовательными.

Это не анти-шаблон, когда вам действительно нужно другое представление классов домена - более плоский, более богатый, более узкий ...

лично я начинаю с класса домена и передаю его, с правильной проверкой в нужных местах. Я могу аннотировать и / или добавить некоторые "вспомогательные" классы, чтобы сделать сопоставления, в базу данных, в форматы сериализации, такие как JSON или XML ... Я всегда могу разделить класс на два, если чувствую, что необходимость.

речь идет о вашей точке зрения-я предпочитаю смотреть на объект домена как на один объект, играющий различные роли, а не на несколько объектов, созданных друг из друга. Если единственной ролью объекта является транспортировка данных, то это DTO.