Почему объекты передачи данных (DTO) являются анти-шаблоном?

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

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


person ntownsend    schedule 17.09.2009    source источник
comment
Возможно, потому, что бизнес-объекты сами могут передавать свои данные, большое вам спасибо!   -  person Zoidberg    schedule 17.09.2009
comment
«Антипаттерн» вполне может быть моей кандидатурой на фразу, 15 минут которой истекли давным-давно. Это синоним того, что я не хочу сейчас оправдывать свои мысли, как будто хорошо известно, что ...   -  person Craig Stuntz    schedule 17.09.2009
comment
Зойдберг, отправка объектов с методами по сети, дала нам CORBA, DCOM и другие возможности, о которых я пытаюсь стереть память. Проблема в том, что рано или поздно люди захотят вызвать эти методы.   -  person Craig Stuntz    schedule 17.09.2009
comment
DTO воплощают принцип DRY, который, к сожалению, в J2EE означает повторять.   -  person joeforker    schedule 17.09.2009


Ответы (11)


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

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

person KLE    schedule 17.09.2009
comment
Пожалуйста, поясните огромную стоимость. Кроме того, скажите, почему нельзя избежать затрат, используя методы генерации кода для генерации классов DTO. - person John Saunders; 18.09.2009
comment
+1. Дважды? Только если вам повезет :-) Проекты, которые дублируют сущности предметной области как DTO, также имеют тенденцию иметь почти такие же, но очень тонко разные компоненты пользовательского интерфейса, дополняющие их. Это 3. И если, не дай бог, происходит какое-то удаленное взаимодействие (веб-сервисы / xml-rpc / что-то еще), вы легко можете добраться до 4 или 5. - person ChssPly76; 18.09.2009
comment
Давайте посмотрим, что первая стоимость - это преобразование их из объекта домена в DataDto. Затем вы конвертируете DataDto в WebDto (или UiDto) за вторую плату. Позже вам нужно будет добавить поле. Итак, вам нужно добавить поле в домен и 2 Dtos, а также процедуры преобразования. Поскольку очень часто WebDtos представляют собой все строки, теперь вам нужно выполнить некоторые вычисления в числовом поле. Итак, теперь вам нужно изменить WebDto и его процедуру преобразования. Есть еще одна цена. Таким образом, у вас есть затраты на время разработки, время отладки и, конечно же, накладные расходы на преобразования. - person Jim Barrows; 18.09.2009
comment
В настоящее время я работаю с корпоративной архитектурой лазаньи с 14 слоями (НЕ ДЕТСКАЯ). Могу заверить вас, что около 11 слоев, предназначенных в основном для передачи данных, не предоставляются бесплатно. - person KarlP; 18.09.2009
comment
Кроме того, хотя я очень люблю генераторы кода при работе с дурацкими проектами, они а) наверняка делают что-то неправильно с самого начала. б) они не приходят бесплатно. - person KarlP; 18.09.2009
comment
@John Под затратами я подразумеваю время разработки, а также создание и копирование объектов во время выполнения. Я согласен, время разработки можно сократить с помощью методов генерации кода, если они хорошо освоены ... но иногда они возникают сами по себе. - person KLE; 18.09.2009
comment
@Karlp спасибо за ваш реальный вклад. Твоя ситуация кажется невероятной. Есть ли место, где вы могли бы дать нам более подробную информацию (может быть, что-то более читаемое, чем некоторые комментарии?). - person KLE; 18.09.2009
comment
Извините, но это просто неверно, и неправильный ответ получил высокую оценку и был принят. Прежде всего, вы можете использовать отражение для генерации DTO на лету. Во-вторых, вы можете использовать корневое определение, например. в системе CASE или в oAW и сгенерируйте BO и DTO (ы). В-третьих, вы можете использовать XSD и JAXB для генерации DTO и использовать DTO в качестве основы для BO, или вы можете сгенерировать оба из XSD ... в любом случае, если кто-то осмелится передать EJB, только что полученный из БД, через подключиться к клиентской программе ... в среде, с которой я работаю, его голова скоро окажется на серебряной пластине ... - person Angel O'Sphere; 28.09.2011
comment
... не говоря уже о том, что он, вероятно, заплатит остаток своей жизни за ущерб, который он мог бы нанести этим. - person Angel O'Sphere; 28.09.2011
comment
Хехе, репутация зависит от активности, а активность связана с возрастом ... Я публикую здесь только иногда, начиная с последних 4 месяцев или около того. Также вы получите репутацию, если ваши ответы будут одобрены или приняты ... Я в основном исправляю ошибки. Как неправильное голосование за этот ответ. Меня не волнует, получу ли я за это репутацию или нет. - person Angel O'Sphere; 03.11.2011
comment
Что вы думаете о Dto и наследовании? - person ramon_salla; 08.01.2013
comment
Я могу понять эту боль здесь ... мое приложение активно использовало объекты состояния, которые были древним названием объектов передачи, и у нас есть данные в объектах спящего режима, а также в объектах состояния ... устаревшая системная архитектура ... уф !!! - person Rachel; 11.03.2013
comment
Просто грустно, что принятый ответ не отвечает на часть Каковы альтернативы - person Snicolas; 07.09.2015
comment
@ AngelO'Sphere. Мне кажется, твое лекарство хуже болезни. По крайней мере, для не очень предприимчивых проектов. Конечно, вы можете использовать какой-нибудь генератор шаблонов, чтобы получить еще больше шаблонов, и обычно он работает хорошо, но с любой проблемой вы потеряете больше времени, чем сэкономили. - person maaartinus; 09.09.2015
comment
Использование генераторов кода иногда указывает на отсутствие языковых функций. К сожалению, Java не поддерживает представление простых структур данных из коробки, в отличие от Haskell, Scala, Swift ... Lombok, кстати, также является генератором кода, с той лишь разницей, что он не генерирует исходный код. - person yeoman; 24.05.2017

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

Я знаю, что это вопрос, ориентированный на Java, но в языках .NET анонимные типы, сериализация и LINQ позволяют создавать DTO «на лету», что сокращает настройку и накладные расходы на их использование.

person Gabe Moothart    schedule 17.09.2009
comment
Мне придется проголосовать против этого ответа из-за вашего упоминания о сериализации анонимных типов. Вы не можете даже вернуть анонимный тип, тем более сериализовать его так же, как вы могли бы сериализовать DTO. - person John Saunders; 18.09.2009
comment
@John, это неверно. Я делаю это все время. Сериализация использует отражение, которое отлично работает с анонимными типами. Просто передайте его сериализатору как объект. И как только он будет сериализован (например, в xml или json), вы, конечно, можете вернуть его из метода. - person Gabe Moothart; 18.09.2009
comment
Гм, Джон, это просто неправда. Вы можете легко сериализовать анонимные типы в JSON. Попробуйте это в приложении MVC: return Json (new {Foo = Hi there!}); Обещаю, все работает отлично. Возможно, лучше, чем неанонимные типы, поскольку анонимные типы обычно не имеют циклов в своих графах объектов, что нарушает сериализатор JSON. - person Craig Stuntz; 18.09.2009
comment
Сериализация Json не является DTO в этом смысле и поэтому не применяется. Тогда, конечно, мои аргументы выше также применимы, в какой-то момент они просто перестают того стоить. - person Jim Barrows; 18.09.2009
comment
Гейб прав, DTO сам по себе не является анти-шаблоном (но может быть использован при неправильном использовании!), Когда нет дублирования данных. Например, BO может агрегировать данные из разных источников в DTO. - person a.s.t.r.o; 23.01.2011
comment
+1. И есть много других причин, помимо экономии полосы пропускания, по которым вам понадобятся DTO. Разрешено ли вам (политикой компании или законом) рассылать каждое поле по сети? Кроме того, в нашей компании наш DAO очень сложен, потому что ему необходимо выполнить все эти оптимизации - работая на уровне обслуживания, я очень рад, что они используют DTO, и не заставляют нас беспокоиться об отношениях, которые имеет Object X к какой-то другой таблице n-to-n. - person user64141; 29.08.2014

DTO an AntiPattern в EJB 3.0 говорит:

Большой вес Entity Beans в спецификациях EJB до EJB 3.0 привел к использованию шаблонов проектирования, таких как объекты передачи данных (DTO). DTO стали легковесными объектами (которые должны были быть самими компонентами управления данными в первую очередь), используемыми для отправки данных по уровням ... теперь спецификация EJB 3.0 делает модель компонента Entity такой же, как и обычный старый объект Java (POJO). С этой новой моделью POJO вам больше не нужно будет создавать DTO для каждой сущности или для набора сущностей ... Если вы хотите отправлять сущности EJB 3.0 через уровень, просто реализуйте java.io.Serialiazable

person aem    schedule 17.09.2009
comment
Верно, когда вы переносите объекты между методами в одной JVM в памяти. Неправда, когда вы на самом деле сериализуете по сети и хотите контролировать глубину сериализации и / или сохранять ленивую загрузку. - person wrschneider; 07.11.2012
comment
Да, и даже в одной и той же JVM вам действительно следует позаботиться о том, чтобы оставаться в той же теме, если вы используете управление транзакциями JEE / Spring. - person Marc; 02.04.2014

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

person Darin Dimitrov    schedule 17.09.2009

Я не думаю, что 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, используют альтернативный упрощенный вид с использованием POJO в качестве объектов домена (часто аннотированных JPA и т. Д.) На одном уровне ... Использование DTO здесь не требуется.

person Jon    schedule 17.09.2009
comment
Вы совершенно правы, что DTO являются хорошим шаблоном, а не анти-шаблоном при использовании в их надлежащий контекст. Ваша вторая ссылка сейчас кажется мертвой, но самое большое злоупотребление, которое я видел, - это когда каждый объект домена имел соответствующий DTO для взаимодействия с базой данных, который не добавлял никакой ценности и вообще не был DTO! - person David; 23.10.2014

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

Эта статья неопределенно описывает некоторые нарушения.

person Ben S    schedule 17.09.2009
comment
В статье гораздо точнее описываются DTO как шаблон, которым можно злоупотреблять. - person Craig Stuntz; 17.09.2009
comment
Это сводится к ответу только по ссылке, для этого действительно нужна хотя бы цитата из статьи. Не знаю, как это удалось не отметить как «Не ответ». - person Nathan Hughes; 17.01.2019
comment
Ссылка мертва, попробуйте https://web.archive.org/web/20110707143818/https://anirudhvyas.com/root/2008/04/19/abuses-of-dto-pattern-in-java-world/ - person Davi Lima; 30.12.2019

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

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

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

person Bealer    schedule 18.09.2009

DTO становится необходимостью, а не АНТИШАБЛОНОМ, когда все объекты вашего домена загружают связанные объекты EAGERly.

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

Чтобы ограничить накладные расходы в этом случае, лучше перенесите DTO.

person javadev    schedule 26.10.2015

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

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

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

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

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

person Rostislav Matl    schedule 22.08.2018

Цель объекта передачи данных - хранить данные из разных источников и затем передавать их в базу данных (или Remote Facade) сразу.

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

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

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

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

person MovGP0    schedule 22.12.2014

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

person jdehaan    schedule 17.09.2009