Я недавно чув , як люди кажуть , що об'єкти передачі даних (DTO) є складовою антішаблоном .
Чому? Які альтернативи?
Я недавно чув , як люди кажуть , що об'єкти передачі даних (DTO) є складовою антішаблоном .
Чому? Які альтернативи?
Відповіді:
Деякі проекти мають усі дані двічі . Один раз як об’єкти домену, і один раз як об'єкти передачі даних.
Це дублювання має величезні витрати , тому архітектура повинна отримати величезну вигоду від цього розділення, щоб воно того варте.
DTO не є антидіаграмою. Коли ви надсилаєте деякі дані по всій лінії зв'язку (скажімо, на веб-сторінку під час виклику Ajax), ви хочете бути впевнені, що ви зберігаєте пропускну здатність, лише надсилаючи дані, які використовуватиме місце призначення. Також часто для шару презентації зручно мати дані у дещо іншому форматі, ніж власний бізнес-об’єкт.
Я знаю, що це питання, орієнтоване на Java, але анонімні типи, серіалізація та LINQ в мовах .NET дозволяють будувати DTO на ходу, що зменшує налаштування та накладні витрати їх використання.
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
Я не думаю, що 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 тут не є зайвим.
Пуристики OO кажуть, що DTO є антидіаграмою, оскільки об'єкти стають представленнями таблиць даних замість реальних об'єктів домену.
Деякі вважають ДТЗ антимоделією через можливі зловживання. Їх часто використовують, коли їх не повинно бути / не потрібно.
У цій статті смутно описані деякі зловживання.
Якщо ви будуєте розподілену систему, то DTO, безумовно, не є анти-зразком. Не всі будуть розвиватися в цьому сенсі, але якщо у вас є (наприклад) відкрита програма Social Social, у якої працює весь JavaScript.
Він опублікує завантаження даних у ваш API. Потім це десеріалізується у певну форму об'єкта, як правило, об'єкт DTO / Request. Потім це можна перевірити, щоб переконатися, що введені дані є правильними перед перетворенням в об'єкт моделі.
На мою думку, це сприймається як анти-шаблон, тому що він неправильно використовується. Якщо ви не побудуєте розподілену систему, швидше за все, вони вам не потрібні.
Метою об’єкта передачі даних є зберігання даних з різних джерел, а потім передача їх у базу даних (або віддалений фасад ) одразу.
Однак модель DTO порушує Принцип єдиної відповідальності , оскільки DTO не тільки зберігає дані, але й передає їх з бази даних / фасаду.
Необхідність відокремлення об'єктів даних від бізнес-об’єктів не є антипаттерном, оскільки, ймовірно, потрібно розділити рівень бази даних у будь-якому випадку.
Замість DTO слід використовувати схеми агрегації та сховища, що розділяє колекцію об'єктів ( агрегат ) та передачу даних ( репозиторій ).
Для передачі групи об'єктів можна використовувати шаблон Unit Of Work , який містить набір сховищ та контекст транзакцій; щоб перенести кожен об'єкт у сукупності окремо в межах транзакції.
DTO стає необхідністю, а не АНТИПАТЕРНЕМ, коли всі ваші доменні об'єкти EAGERly завантажують пов'язані об'єкти.
Якщо ви не робите DTO, у вас будуть непотрібні передані об’єкти з бізнес-рівня на ваш клієнт / веб-шар.
Щоб обмежити накладні витрати для цього випадку, швидше перенесіть DTO.
Питання має бути не "чому", а " коли ".
Безумовно, це анти-шаблон, коли єдиним результатом його використання є більш висока вартість - час роботи або обслуговування. Я працював над проектами, що мають сотні DTO, ідентичні класам сутностей бази даних. Кожен раз, коли ви хотіли додати одне поле, яке ви рекламуєте, щоб додати ідентифікатор, як чотири рази - до DTO, сутності, перетворення з DTO в класи домен або класи, обернене перетворення, ... Ви забули деякі місця та отримані дані непослідовний.
Це не анти-шаблон, коли вам дійсно потрібне різне представлення класів доменів - більш рівне, більш насичене, вузьке, ...
Особисто я починаю з доменного класу і передаю його навколо, при належній перевірці в потрібних місцях. Я можу коментувати та / або додавати кілька "помічників" класів для створення відображень, баз даних, таких форматів серіалізації, як JSON чи XML ... Я завжди можу розділити клас на два, якщо відчуваю потребу.
Це стосується вашої точки зору - я вважаю за краще розглядати доменний об’єкт як один об'єкт, який грає різні ролі, а не кілька об'єктів, створених один від одного. Якщо єдиною роллю об'єкта є транспортування даних, то це DTO.
Я думаю, що люди означають, що це може бути антидіаграмою, якщо ви реалізуєте всі віддалені об'єкти як DTO. DTO - це просто набір атрибутів, і якщо у вас є великі об'єкти, ви завжди передавали б усі атрибути, навіть якщо вони вам не потрібні та не користуються ними. В останньому випадку віддайте перевагу використанню шаблону проксі.