Я недавно слышал , как люди говорят , что объекты передачи данных (DTO) являются составной антишаблоном .
Зачем? Какие есть альтернативы?
Я недавно слышал , как люди говорят , что объекты передачи данных (DTO) являются составной антишаблоном .
Зачем? Какие есть альтернативы?
Ответы:
В некоторых проектах все данные хранятся дважды . Один раз как объекты домена и один раз как объекты передачи данных.
Это дублирование обходится дорого , поэтому архитектура должна получить огромную выгоду от этого разделения, чтобы оно того стоило.
DTO - это не антипаттерн. Когда вы отправляете некоторые данные по сети (например, на веб-страницу в вызове Ajax), вы хотите быть уверены, что сохраняете полосу пропускания, отправляя только данные, которые будет использовать пункт назначения. Кроме того, часто для уровня представления удобно иметь данные в формате, несколько отличном от формата собственного бизнес-объекта.
Я знаю, что это вопрос, ориентированный на Java, но в языках .NET анонимные типы, сериализация и LINQ позволяют создавать DTO «на лету», что сокращает время настройки и накладные расходы на их использование.
DTO 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
Я не думаю, что 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 здесь не требуется.
Сторонники объектно-ориентированного подхода сказали бы, что DTO - это анти-шаблон, потому что объекты становятся представлениями таблиц данных вместо реальных объектов предметной области.
Некоторые считают DTO антипаттерном из-за их возможных злоупотреблений. Их часто используют, когда они не должны / не нужны.
В этой статье расплывчато описаны некоторые нарушения.
Если вы создаете распределенную систему, то DTO, безусловно, не антипаттерн. Не все будут развиваться в этом смысле, но если у вас есть (например) приложение Open Social, все работают на JavaScript.
Он отправит загрузку данных в ваш API. Затем он десериализуется в некоторую форму объекта, обычно в объект DTO / Request. Затем это можно проверить, чтобы убедиться, что введенные данные верны, перед преобразованием в объект модели.
На мой взгляд, это антипаттерн, потому что его неправильно используют. Если вы не создаете распределенную систему, скорее всего, они вам не понадобятся.
Намерение передачи данных объекта для хранения данных из разных источников , а затем передать его в базу данных (или удаленный фасад ) сразу.
Однако шаблон DTO нарушает принцип единой ответственности , поскольку DTO не только хранит данные, но и передает их из или в базу данных / фасад.
Необходимость отделить объекты данных от бизнес-объектов не является антипаттерном, поскольку, вероятно, в любом случае потребуется отделить уровень базы данных .
Вместо DTO вы должны использовать шаблоны Aggregate и Repository, которые разделяют коллекцию объектов ( Aggregate ) и передачу данных ( Repository ).
Для передачи группы объектов вы можете использовать шаблон « Единица работы» , который содержит набор репозиториев и контекст транзакции; для того, чтобы передать каждый объект в совокупности отдельно в рамках транзакции.
DTO становится необходимостью, а не АНТИШАБЛОНОМ, когда все объекты вашего домена загружают связанные объекты EAGERly.
Если вы не создадите DTO, у вас будут ненужные объекты, перенесенные с вашего бизнес-уровня на ваш клиентский / веб-уровень.
Чтобы ограничить накладные расходы в этом случае, лучше перенесите DTO.
Вопрос должен быть не «почему», а « когда ».
Безусловно, это анти-шаблон, когда только результатом его использования является более высокая стоимость - время выполнения или обслуживание. Я работал над проектами, имеющими сотни DTO, идентичных классам сущностей базы данных. Каждый раз, когда вы хотели добавить одно поле, которое вы рекламируете, чтобы добавить идентификатор, например, четыре раза - в DTO, в сущность, в преобразование из DTO в классы или сущности домена, обратное преобразование, ... Вы забыли некоторые места и данные, полученные противоречивы.
Это не антипаттерн, когда вам действительно нужно другое представление классов предметной области - более плоское, более богатое, более узкое, ...
Лично я начинаю с класса предметной области и передаю его, тщательно проверяя в нужных местах. Я могу аннотировать и / или добавлять некоторые «вспомогательные» классы для сопоставления с базой данных, с форматами сериализации, такими как JSON или XML ... Я всегда могу разделить класс на два, если чувствую в этом необходимость.
Это касается вашей точки зрения - я предпочитаю рассматривать объект предметной области как один объект, играющий различные роли, а не как несколько объектов, созданных друг из друга. Если единственная роль объекта - транспортировка данных, то это DTO.
Я думаю, люди имеют в виду, что это может быть анти-шаблон, если вы реализуете все удаленные объекты как DTO. DTO - это просто набор атрибутов, и если у вас есть большие объекты, вы всегда будете передавать все атрибуты, даже если они вам не нужны или не используете их. В последнем случае лучше использовать шаблон прокси.