Чому об’єкти передачі даних (DTO) є антидіаграмою?


132

Я недавно чув , як люди кажуть , що об'єкти передачі даних (DTO) є складовою антішаблоном .

Чому? Які альтернативи?


11
Можливо, тому, що бізнес-об’єкти самі здатні транспортувати власні дані, дуже дякую!
Зойдберг

13
"Анти-шаблон" цілком може стати моїм номінантом за фразу, 15 хвилин якої минуло давно. Синонім до цього моменту "Мені не байдуже обгрунтовувати своє мислення", на кшталт "Загальновідомо, що ..."
Craig Stuntz

6
Зойдберг, надсилаючи об’єкти методами по дроту, дав нам CORBA, DCOM та інші враження, про які я намагаюся стерти свою пам'ять. Біда в тому, що рано чи пізно люди хочуть назвати ці методи.
Крейг Стунц

10
DTOS втілюють принцип DRY, який нещасливо в J2EE стоїть за зроби повторюватися.
joeforker

Ви можете прочитати це: Об'єкт передачі даних - це сором
yegor256

Відповіді:


139

Деякі проекти мають усі дані двічі . Один раз як об’єкти домену, і один раз як об'єкти передачі даних.

Це дублювання має величезні витрати , тому архітектура повинна отримати величезну вигоду від цього розділення, щоб воно того варте.


5
Будь ласка, детальніше уточнюйте "величезну вартість". Крім того, скажіть, чому вартість не може бути усунена за допомогою методів генерації коду для генерації класів DTO.
Джон Сондерс

70
+1. Двічі? Тільки якщо вам пощастить :-) Проекти, які дублюють об'єкти домену як DTO, також мають тенденцію мати майже однакові, але о-о-так-тонко різні інтерфейси для доповнення. Це 3. І якщо, не дай бог, відбувається якесь видалення (веб-сервіси / xml-rpc / що завгодно), ви можете легко дістатися до 4 або 5.
ChssPly76

17
В даний час я працюю з архітектурою лазаньї з 14 шарами (не KIDDING). Я можу запевнити, що 11-ти або більше шарів, які в основному є транслятором даних, не є безкоштовними.
KarlP

10
Крім того, хоча я абсолютно люблю генератори коду під час роботи з дурними конструкціями, вони є: a) впевненою річчю, що ви робите це неправильно для початку. б) вони не приходять безкоштовно.
KarlP

7
Вибачте, але це просто неправильно, і за неправильну відповідь було оголошено високу і прийняту. Перш за все, ви можете використовувати відображення для генерації DTO на льоту. По-друге, ви можете використовувати "кореневе визначення", наприклад, у системі CASE або в oAW та генерувати BO та DTO (s). По-третє, ви можете використовувати XSD і JAXB для генерації DTO і використовувати DTO в якості бази для BO, або ви можете генерувати обидва з XSD ... у будь-якому разі, якщо хтось наважиться би перенести EJB, щойно отриманий з БД підключення до клієнтської програми ... У середовищі, в якій я працюю, його голова досить скоро буде на срібній тарілці ...
Angel O'Sphere

128

DTO не є антидіаграмою. Коли ви надсилаєте деякі дані по всій лінії зв'язку (скажімо, на веб-сторінку під час виклику Ajax), ви хочете бути впевнені, що ви зберігаєте пропускну здатність, лише надсилаючи дані, які використовуватиме місце призначення. Також часто для шару презентації зручно мати дані у дещо іншому форматі, ніж власний бізнес-об’єкт.

Я знаю, що це питання, орієнтоване на Java, але анонімні типи, серіалізація та LINQ в мовах .NET дозволяють будувати DTO на ходу, що зменшує налаштування та накладні витрати їх використання.


15
@John, це неправильно. Я роблю це постійно. У серіалізації використовується рефлексія, яка добре працює на анонімних типах. Просто передайте його в серіалізатор як об’єкт. І як тільки він буде серіалізований (наприклад, у xml або json), звичайно, ви можете повернути його з методу.
Гейб Мутхарт

8
Гм, Джон, це просто неправда. Ви можете просто серіалізувати анонімні типи до JSON. Спробуйте це в додатку MVC: поверніть Json (новий {Foo = "Привіт!}); Я обіцяю, що він працює чудово. Краще, можливо, ніж неанонімні типи, оскільки анонімні типи зазвичай не мають циклів у своїх об'єктних графіках. , які розщеплюють серіалізатор JSON.
Craig Stuntz

1
Серіалізація Json не є DTO в цьому сенсі, і тому не застосовується. Тоді, звичайно, застосовуються і мої аргументи, наведені вище, і в якийсь момент вони просто перестають вартувати цього.
Джим Барроуз

1
Gabe має рацію, DTO не є антидіаграмою сама по собі (але може бути використана неправильно!), Коли немає дублювання даних. Наприклад, БО може агрегувати дані з різних джерел у DTO.
астро

3
+1. І є ще безліч інших причин, крім збереження пропускної здатності, які вам потрібні DTO. Ви навіть ДОЗВОЛЕНО (за політикою чи законом компанії) надсилати кожне поле по всій лінії? Крім того, в нашій компанії наш DAO дуже складний, тому що він повинен зробити всі ці оптимізації - працюючи на рівні сервісу, я дуже радий, що вони використовують DTO і не змушують нас хвилюватися щодо відносин, які має Object X до якоїсь іншої таблиці n-to-n.
user64141

25

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

Суттєвий характер сутності суб'єктів господарювання в специфікаціях EJB до EJB 3.0 призвів до використання таких моделей дизайну, як об'єкти передачі даних (DTO). DTO стали легкими об'єктами (які, в першу чергу, повинні бути самими бобами сутності), що використовуються для передачі даних по рівнях ... тепер специфікація EJB 3.0 робить модель bean Entity такою ж, як звичайний старий об'єкт Java (POJO). З цією новою моделлю POJO вам більше не потрібно буде створювати DTO для кожної сутності або для набору сутностей ... Якщо ви хочете відправити об'єкти EJB 3.0 через рівень, зробіть їх просто реалізацією java.io.Serialiazable


6
Щоправда, коли ви переносите об'єкти між методами в одному JVM, в пам'яті. Неправда, коли ви насправді серіалізуєте по дроту та хочете контролювати, наскільки глибоко серіалізувати та / або зберігати ледачу завантаження.
wrschneider

Так, і навіть у тому ж JVM вам слід потурбуватися про те, щоб залишитися в тому ж самому теді, якщо ви використовуєте JEE / Spring управління транзакціями.
Марк

20

Я не думаю, що DTO самі по собі є антидіаграмою, але існують антидіаграми, пов'язані з використанням DTO. Білл Дадні називає приклад вибуху DTO:

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

Тут також згадується ряд зловживань ЗНО:

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

Вони виникли через трирівневі системи (як правило, використовуючи EJB як технологію) як засіб передачі даних між ярусами. Більшість сучасних систем Java на основі каркасів, таких як Spring, мають альтернативний спрощений вигляд, використовуючи POJO в якості об’єктів домену (часто коментується JPA тощо) в один рівень ... Використання DTO тут не є зайвим.


3
Ви абсолютно праві, що DTO - це хороший зразок , а не анти-шаблон, коли він використовується у відповідному контексті. Наразі ваше друге посилання виявляється мертвим, але найбільше зловживання, яке я бачив, - це те, коли кожен доменний об’єкт мав відповідне "DTO" для взаємодії з базою даних, що не додало ніякої цінності і зовсім не було DTO!
Девід

19

Пуристики OO кажуть, що DTO є антидіаграмою, оскільки об'єкти стають представленнями таблиць даних замість реальних об'єктів домену.


9

Деякі вважають ДТЗ антимоделією через можливі зловживання. Їх часто використовують, коли їх не повинно бути / не потрібно.

У цій статті смутно описані деякі зловживання.


1
Стаття набагато точніше описує DTO як зразок, яким можна зловживати.
Craig Stuntz

Це означає лише відповідь на посилання, вона справді потребує хоча б цитати зі статті. не знаю, як це вдалося не позначити як Not An Answer.
Натан Х'юз


7

Якщо ви будуєте розподілену систему, то DTO, безумовно, не є анти-зразком. Не всі будуть розвиватися в цьому сенсі, але якщо у вас є (наприклад) відкрита програма Social Social, у якої працює весь JavaScript.

Він опублікує завантаження даних у ваш API. Потім це десеріалізується у певну форму об'єкта, як правило, об'єкт DTO / Request. Потім це можна перевірити, щоб переконатися, що введені дані є правильними перед перетворенням в об'єкт моделі.

На мою думку, це сприймається як анти-шаблон, тому що він неправильно використовується. Якщо ви не побудуєте розподілену систему, швидше за все, вони вам не потрібні.


4

Метою об’єкта передачі даних є зберігання даних з різних джерел, а потім передача їх у базу даних (або віддалений фасад ) одразу.

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

Необхідність відокремлення об'єктів даних від бізнес-об’єктів не є антипаттерном, оскільки, ймовірно, потрібно розділити рівень бази даних у будь-якому випадку.

Замість DTO слід використовувати схеми агрегації та сховища, що розділяє колекцію об'єктів ( агрегат ) та передачу даних ( репозиторій ).

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


4

DTO стає необхідністю, а не АНТИПАТЕРНЕМ, коли всі ваші доменні об'єкти EAGERly завантажують пов'язані об'єкти.

Якщо ви не робите DTO, у вас будуть непотрібні передані об’єкти з бізнес-рівня на ваш клієнт / веб-шар.

Щоб обмежити накладні витрати для цього випадку, швидше перенесіть DTO.


1

Питання має бути не "чому", а " коли ".

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

Це не анти-шаблон, коли вам дійсно потрібне різне представлення класів доменів - більш рівне, більш насичене, вузьке, ...

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

Це стосується вашої точки зору - я вважаю за краще розглядати доменний об’єкт як один об'єкт, який грає різні ролі, а не кілька об'єктів, створених один від одного. Якщо єдиною роллю об'єкта є транспортування даних, то це DTO.


1

Я думаю, що люди означають, що це може бути антидіаграмою, якщо ви реалізуєте всі віддалені об'єкти як DTO. DTO - це просто набір атрибутів, і якщо у вас є великі об'єкти, ви завжди передавали б усі атрибути, навіть якщо вони вам не потрібні та не користуються ними. В останньому випадку віддайте перевагу використанню шаблону проксі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.