Що таке об’єкт передачі даних?


218

Що таке об'єкт передачі даних?

У MVC є модельні класи DTO, і якщо ні, то які відмінності і чи потрібні нам обидва?


@ yegor256, і факт, що книга в цій статті знає, як отримати дані з API, а також як зберігати дані в БД і, таким чином, порушуючи SRP, це нормально?
Бетліста

Відповіді:


222

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

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

Іншим використанням для DTO може бути інкапсуляція параметрів для викликів методів. Це може бути корисно, якщо метод має більше 4 або 5 параметрів.

Використовуючи схему DTO, ви також використовуєте збирачі DTO. Асемблери використовуються для створення DTO з об'єктів домену, і навпаки.

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


7
"DTO створює чудові моделі в шаблоні MVC" - але чи не повинна модель містити всі дані об'єкта, і DTO буде оптимізовано з частиною даних? Якщо у мене є модель A і мені потрібно передати її до двох підсистем, чи будуть A_DTO_1 та A_DTO_2 із відповідними полями кожної? "DTO можуть бути інкапсулювати параметри для викликів методу" -> Отже, кожен клас, який обертає параметри, є DTO, навіть якщо це не розподілена система? Чи не є моделями в MVC об’єкт домену?
Ярон Наве

2
Відповідаючи на ваше перше запитання, я не думаю, що говорили про те саме. Модель в MVC не обов'язково повинна бути класом з вашої доменної моделі. Сказавши це, це добре могло бути. Використання DTO викреслює всі непотрібні речі. Просто залежить від архітектури, яку ви збираєтеся. Я не впевнений, як саме відповісти на ваше друге запитання. Незалежно від того, чи це через провід, чи ні, він все ще є об'єктом, який містить в собі купу даних, що передаються між (під) системами, тому я можу стверджувати, що це DTO.
Бенні Галлетт

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

2
@Wix, хороший момент. Однак я заперечую, що це нормально, якщо це семантично правильно (скажімо, якщо ви передаєте клас налаштувань із властивостями, а не самими властивостями як значеннями). Те, що ви не повинні робити, це накинути всі аргументи заради передачі одного об'єкта, оскільки вони можуть бути непов’язаними і спричинити згодом кошмари.
Арам Кочарян

3
DTO не слід використовувати для інкапсуляції параметрів для викликів методів (що зробить їх LocalDTO), вони були введені в контексті віддалених інтерфейсів: martinfowler.com/bliki/LocalDTO.html
Rui

28

Визначення DTO можна знайти на сайті Мартіна Фаулера . DTO використовуються для передачі параметрів методам і як типи повернення. Дуже багато людей використовують такі в інтерфейсі, але інші надувають доменні об’єкти від них.


22

DTO є тупим об'єктом - він просто містить властивості, має getters і setters, але немає жодної іншої логіки будь-якого значення (крім, можливо, порівняння () або рівності () реалізації).

Зазвичай модельні класи в MVC (якщо тут .net MVC) - це DTO, або колекції / агрегати DTO


3
Те, що ви описуєте, є LocalDTO: martinfowler.com/bliki/LocalDTO.html
Rui

3
Один випадок, коли корисно використовувати щось на зразок DTO, це коли у вас є суттєва невідповідність моделі в вашому презентаційному шарі та базової моделі домену. У цьому випадку має сенс зробити фасад / шлюз для презентації, який відображається з доменної моделі та представляє зручний для презентації інтерфейс.
Амітабха

14

Загалом об'єкти цінності повинні бути незмінними. Як і об'єкти Integer або String в Java. Ми можемо використовувати їх для передачі даних між програмними рівнями. Якщо шари програм або послуги, що працюють у різних віддалених вузлах, наприклад, у середовищі мікросервісів або у застарілому додатку Java Enterprise. Ми повинні зробити майже точні копії двох класів. Тут ми зустріли DTO.

|-----------|                                                   |--------------|
| SERVICE 1 |--> Credentials DTO >--------> Credentials DTO >-- | AUTH SERVICE |
|-----------|                                                   |--------------|

У застарілих системах Java Enterprise Systems DTO можуть містити в собі різні речі EJB.

Я не знаю, це найкраща практика чи ні, але я особисто використовую ціннісні об’єкти у своїх весняних проектах MVC / Boot:

        |------------|         |------------------|                             |------------|
-> Form |            | -> Form |                  | -> Entity                   |            |
        | Controller |         | Service / Facade |                             | Repository |
<- View |            | <- View |                  | <- Entity / Projection View |            |
        |------------|         |------------------|                             |------------|

Шар контролера не знає, що таке сутність. Він спілкується з об'єктами форми та переглядає значення . Об'єкти форми мають анотації валідації JSR 303 (наприклад, @NotNull), а об'єкти перегляду значення мають анотації Джексона для користувацької серіалізації. (наприклад, @JsonIgnore)

Службовий рівень спілкується з шаром сховища за допомогою об'єктів Entity. Об'єкти суб'єктів господарювання мають анотації JPA / Hibernate / Spring Data. Кожен шар спілкується лише з нижчим шаром. Міжшаровий зв'язок заборонений через кругову / циклічну залежність.

User Service ----> XX CANNOT CALL XX ----> Order Service

Деякі рамки ORM мають можливість проекції за допомогою додаткових інтерфейсів або класів. Таким чином сховища можуть повертати об'єкти View безпосередньо. Там для вас не потрібна додаткова трансформація.

Наприклад, це наша організація Користувача:

@Entity
public final class User {
    private String id;
    private String firstname;
    private String lastname;
    private String phone;
    private String fax;
    private String address;
    // Accessors ...
}

Але вам слід повернути список страждаючих користувачів, який містить лише id, ім'я, прізвище. Потім ви можете створити об'єкт перегляду значення для проекції ORM.

public final class UserListItemView {
    private String id;
    private String firstname;
    private String lastname;
    // Accessors ...
}

Ви можете легко отримати болісний результат із шару сховища. Завдяки весні ви також можете використовувати просто інтерфейси для проекцій.

List<UserListItemView> find(Pageable pageable);

Не хвилюйтесь, що інші BeanUtils.copyметоди конверсійних операцій спрацьовують чудово.


11
  1. Для мене найкращою відповіддю на питання, що таке DTO, є те, що DTO - це прості об'єкти, які не повинні містити жодної ділової логіки чи впровадження методів, які потребували б тестування .
  2. Зазвичай ваша модель (з використанням шаблону MVC) - це інтелектуальні моделі, і вони можуть містити безліч / деяких методів, які виконують окремі операції для цієї моделі конкретно (не ділова логіка, це має бути в контролерах). Однак, коли ви передаєте дані (наприклад, виклик звідкись кінцевої точки REST ( GET/ POST/ що завгодно) або використання веб-сервісу за допомогою SOA тощо), ви не бажаєте передавати об'єкт великого розміру з кодом, який не потрібен кінцева точка, буде споживати дані та уповільнюватиме передачу.

Чому ділова логіка повинна бути в контролерах?
AlexioVay

6

За допомогою MVC об'єкти передачі даних часто використовуються для зіставлення моделей домену на більш прості об'єкти, які в кінцевому підсумку будуть відображатися поданням.

З Вікіпедії :

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


3
Об'єкт значення не є DTO .
coderpc

0

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


0

DefN

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

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

Квар

DTO можна змоделювати за допомогою полів або властивостей, але хтось винайшов дуже корисний контейнер даних під назвою Cvar. Це посилання на значення. Коли моделювання DTO моделюється за допомогою базових властивостей , які я називаю , модулі можуть бути налаштовані на обмін пам'яттю купи і тим самим спільно працювати над ним. Це повністю виключає передачу параметрів та зв'язок O2O з вашого коду. Іншими словами, DTO, що мають референтні властивості, дозволяють коду домогтися нульового зв'язку .

    class Cvar { ... }

    class Cvar<T> : Cvar
    {
        public T Value { get; set; }
    }

    class MyDTO
    {
        public Cvar<int> X { get; set; }
        public Cvar<int> Y { get; set; }
        public Cvar<string> mutableString { get; set; } // >;)
    }

Джерело: http://www.powersemantics.com/

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

    // a dynamic DTO
    class CvarRegistry : Dictionary<string, Cvar> { }

Зміст

Примітка: оскільки Wix позначив використання DTO для організації параметрів як "анти-шаблон", я дам авторитетну думку.

    return View(model);  // MVC disagrees

Моя спільна архітектура замінює схеми дизайну. Зверніться до моїх веб-статей.

Параметри забезпечують негайне керування каркасною машиною. Якщо ви використовуєте постійний контроль і тому не потребуєте негайного контролю, вашим модулям не потрібні параметри. У моїй архітектурі немає жодної. Поточна конфігурація машин (методів) додає складності, але також значення (продуктивності), коли параметри є типовими типами. Однак параметри типового типу змушують споживача спричиняти промахи кешу, щоб все-таки отримати значення з купи - отже, просто налаштуйте споживача на еталонні властивості. Факт машинобудування: опора на параметри є своєрідною попередньою оптимізацією, оскільки переробка (виготовлення компонентів) сама по собі є відходами. Додаткову інформацію див. У моїй статті W. http://www.powersemantics.com/w.html .

Фаулер і компанія можуть усвідомити переваги DTO за межами розподіленої архітектури, якби вони коли-небудь знали будь-яку іншу архітектуру. Програмісти знають лише розподілені системи. Інтегровані системи спільної роботи (він же виробництво, також виробництво) - це те, що мені довелося стверджувати як власну архітектуру, тому що я перший написав код таким чином.

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

Немає нічого поганого в моделюванні обробки як купа непотрібних офісних службовців, які працюють електронною поштою один з одним, не зберігаючи слід електронної пошти, за винятком усієї додаткової роботи та головного болю, який вона створює при роботі з логістикою та проблемами повернення. Правильно модельований розподілений процес приєднує документ (активну маршрутизацію) до продукту, що описує, з яких операцій він вийшов і на який піде. Активна маршрутизація - це копія маршрутизації джерела процесу, яка записується до початку процесу. У разі дефекту чи іншої надзвичайної зміни активну маршрутизацію модифікують, щоб включити кроки операції, на які вона буде надіслана. Потім це припадає на всю працю, яка пішла на виробництво.

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