Какой смысл использовать DTO (объекты передачи данных)?

132

Какой смысл использовать DTO и является ли это устаревшей концепцией? Я использую POJO в слое представления для передачи и сохранения данных. Могут ли эти POJO рассматриваться как альтернатива DTO?

Винот Кумар СМ
источник
10
Но POJO может быть DTO, а DTO может быть реализовано с POJO. Вы сравниваете яблоки и апельсины.
Эйфорический
3
Почему хорошие идеи должны быть устаревшими? Посмотри на Лисп. Помимо шуток, я согласен с Euphoric: я обычно реализую DTO, используя POJO. Я до сих пор считаю, что DTO - это очень простая (KISS) и полезная концепция.
Джорджио
Нет никакого смысла, это анти-паттерн, см .: « Объект передачи данных - позор»
yegor256

Ответы:

115

DTO является шаблоном и не зависит от реализации (POJO / POCO). DTO говорит, что, поскольку каждый вызов любого удаленного интерфейса стоит дорого, ответ на каждый вызов должен принести как можно больше данных. Таким образом, если требуется несколько запросов для доставки данных для конкретной задачи, данные, которые должны быть доставлены, могут быть объединены в DTO, так что только один запрос может принести все необходимые данные. Каталог шаблонов архитектуры корпоративных приложений содержит более подробную информацию.

DTO - фундаментальная концепция, а не устаревшая.

Тед
источник
9
Вы можете найти их под разными именами, так как в наши дни, похоже, каждый заново изобретает колесо
linkerro
3
Как и «Объект значения».
Тед
2
@linkerro: Правда: я думаю, что многие люди должны тратить больше времени на чтение материалов, которые уже были изобретены, а не заново изобретать их сами. Вновь придуманные вещи всегда будут менее зрелыми.
Джорджио
10
@ Джорджио Есть много разработчиков, которые все еще работают с идеями, которые никогда не должны были появиться. Я хотел бы, чтобы больше разработчиков подвергали сомнению каждую идею, о которой они читают.
Эрик Реппен
59

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

Что является несколько устаревшим , является понятие того DTOs , которые не содержат никакой логики вообще, используются только для передачи данных и «карту» из объектов предметной области перед передачей клиенту, и отображается для просмотра моделей , прежде чем передать их в слой дисплея. В простых приложениях доменные объекты часто могут напрямую использоваться как DTO и передаваться непосредственно на уровень отображения, так что существует только одна унифицированная модель данных. Для более сложных приложений вы не хотите предоставлять клиенту всю модель домена, поэтому необходимо сопоставление моделей домена и DTO. Наличие отдельной модели представления, которая дублирует данные из DTO, почти никогда не имеет смысла.

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

В частности, Entity Beans в J2EE до стандарта EJB 3 не были POJO и вместо этого были прокси-объектами, созданными сервером приложений - просто было невозможно отправить их клиенту, поэтому у вас не было выбора использовать отдельный слой DTO - это было обязательно.

Майкл Боргвардт
источник
2
Будучи разработчиком пользовательского интерфейса, играющим более универсальную роль, я определенно обнаружил феномен Mapper.Map в нашей кодовой базе, ошеломляющий. Почему DTO не может просто сопоставить себя?
Эрик Реппен
1
@ErikReppen Основным преимуществом является разделение моделей вашего домена и DTO. Если ваш DTO отображает сам себя, ему нужна ссылка на модель вашего домена.
Александр Дерк
17

Хотя DTO не является устаревшим шаблоном, он часто применяется без необходимости, что может сделать его устаревшим.

Наиболее неправильно используемый шаблон в сообществе Java Enterprise - DTO. DTO был четко определен как решение проблемы распространения. DTO должен был представлять собой грубый контейнер данных, который эффективно переносит данные между процессами (уровнями). ~ Адам Бьен

Например, скажем, у вас есть JSF ManagedBean. Общий вопрос заключается в том, должен ли бин содержать ссылку на сущность JPA напрямую или он должен поддерживать ссылку на некоторый промежуточный объект, который впоследствии преобразуется в сущность. Я слышал, что этот промежуточный объект называется DTO, но если ваши ManagedBeans и сущности работают в одной и той же JVM, то использование шаблона DTO дает мало преимуществ.

Рассмотрим аннотации Bean Validation. Ваши сущности JPA, вероятно, снабжены валидациями @NotNull и @Size. Если вы используете DTO, вам нужно будет повторить эти проверки в DTO, чтобы клиентам, использующим ваш удаленный интерфейс, не нужно было отправлять сообщение, чтобы узнать, что они не прошли базовую проверку. Представьте себе всю эту дополнительную работу по копированию аннотаций Bean Validation между вашим DTO и Entity, но если ваш View и Entities работают в одной и той же JVM, нет необходимости выполнять эту дополнительную работу: просто используйте Entities.

Ссылка IAmTheDude на Каталог шаблонов архитектуры корпоративных приложений предоставляет краткое объяснение DTO, и вот еще несколько ссылок, которые я нашел освещающими:

Давидс
источник
3
Есть предложение: «... но если ваши ManagedBeans и сущности работают в одной и той же JVM, то использование шаблона DTO дает мало преимуществ» . В компаниях существует множество приложений среднего размера, которые тупо внедряют шаблон DTO без какой-либо выгоды. Он просто добавляет бесполезный «слой копирования». Люди, создавшие эти системы, не осознавали, что менеджер сущностей Java EE 5+ отсоединяет сущности после завершения транзакции и делает их фактическими DTO. Таким образом, для веб-приложений с одной JVM тип шаблона устарел . Кажется, это реликвия разработчиков бэкэнда J2EE ...
Kawu
Но что такое «JSF ManagedBean» и «JPA Entity»? Если они не устарели, вы сможете объяснить их, используя термины, не зависящие от фреймворка и языка.
U Avalos
8

Точно нет! Совсем недавно я усвоил уроки о том, как лучше использовать DTO, а не бизнес-объект, который вы используете (возможно, привязанный к вашему ORM mapper).

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

Juri
источник
1

Я обнаружил, что DTO особенно полезны, так как содержат логику для ответов API. С этим шаблоном легко управлять различными типами ответов от объектов к различным форматам в тестируемой манере. Используя этот шаблон в моей текущей роли, мы смогли начать тестировать форматы ответов для наших API, что было очень полезно, поскольку наш стек становится более изоморфным для различных клиентов (http / mobile). Определенно не устарел.

zquintana
источник