Для разработчиков, которые избегают написания методов для моделей

Что такое ДТО?

Мартин Фаулер определяет DTO как объект, который переносит данные между процессами, чтобы уменьшить количество вызовов методов.

Класс, представляющий DTO, не имеет методов.

Но каковы пороки DTO?

Первое: дублирование кода

Дублирование кода — самая распространенная болезнь, от которой страдает приложение, широко использующее DTO.

Взгляните на диаграмму ниже.

Пока класс Product является DTO, вы, вероятно, создадите тот же код, который написал другой разработчик или даже вы в другом классе некоторое время назад.

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

Также невозможно использовать полиморфизм, который приводит к дублированию кода, похожему на повторяющееся выражение when (if).

Второе: большие и сложные зависимые классы

DTO не имеет методов. Все методы, выполняющие вычисления на основе элементов DTO, относятся к зависимому классу.

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

Третье: передача/хранение данных не является ответственностью

Я спросил разработчиков, использующих DTO, почему они это делают. Самый распространенный вопрос был: «Из-за того, что DTO передают/хранят данные. Это их обязанность в соответствии с принципом единственной ответственности (позже SRP). В обязанности DTO входит передача/хранение данных».

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

Существует еще один принцип, согласно которому метод должен делать одну и только одну вещь и делать ее хорошо.

Эти два принципа на первый взгляд похожи. Вот почему люди путаются.

Они больше концентрируются на слове «ответственность», а не на определении SRP. Они думают, что у класса есть одна обязанность, что означает, что класс делает одну вещь. Но это совершенно неверный вывод. Одна ответственность означает, что класс должен нести ответственность перед одним и только одним субъектом. Насколько я понимаю, SRP больше касается людей, а не того, что делает объект.

DTO ничего не делают, потому что у них нет методов. Вот почему у них нет поведения. Поэтому у них нет обязанностей.

Когда можно использовать DTO

Можно использовать DTO для анализа объекта JSON, полученного от REST API.

Можно использовать DTO для передачи данных для просмотра, чтобы что-то показать.

Можно использовать DTO, если все расчеты выполняет сервер.

Также можно использовать DTO, если у класса вообще нет логики.

Как уменьшить использование DTO?

  • Напишите методы для классов.
  • Не позволяйте клиентскому коду выполнять вычисления вне класса.
  • Переместите логику, использующую члены класса, в методы класса. Делайте это столько, сколько сможете. Но не забудьте принять во внимание принцип разделения интересов.

Как понять, к какому классу должна принадлежать логика?

Должен применяться принцип информационного эксперта.