Data Transfer Object Is a Shame

The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:

DTO, насколько я понимаю, является одной из основ ОРМ-шаблона проектирования, который я просто “обожаю”. Но давайте перейдем к сути: DTO - это просто позор, и человек, который его изобрел, просто неправ. Нет оправдания тому, что он сделал.

Кстати, насколько мне известно, его звали Мартин Фаулер. Возможно, он не был единственным изобретателем DTO, но он сделал его легальным и рекомендовал его использование. Со всем уважением, он просто был неправ.

Основная идея объектно-ориентированного программирования заключается в скрытии данных за объектами. У этой идеи есть название: инкапсуляция. В ООП данные не должны быть видимыми. Объекты должны иметь доступ только к данным, которые они инкапсулируют, и никогда не к данным, инкапсулированным другими объектами. По этому принципу не может быть споров - это суть ООП.

Однако, DTO полностью противоречит этому принципу.

Давайте рассмотрим практический пример. Предположим, что это сервис, который получает JSON-документ из некоторого RESTful API и возвращает DTO, которое мы затем можем сохранить в базе данных:

Предполагаю, что произойдет внутри метода loadBookById():

Я правильно понимаю? Думаю, да. Мне уже противно это смотреть. В любом случае, продолжаем. Вот что, скорее всего, произойдет в методе saveNewBook() (я использую чистый JDBC):

Эта Книга является классическим примером шаблона проектирования передачи данных (data transfer object). Все, что она делает, это передает данные между двумя частями кода, двумя процедурами. Объект book достаточно глуп. Он умеет делать только … ничего. Он не выполняет никаких действий. Фактически, это даже не объект, а пассивная и анемичная структура данных.

Какой же дизайн является правильным? Есть несколько вариантов. Например, этот выглядит хорошим для меня:

Это то, что происходит в bookById():

Вот что происходит в Book.save():

Что произойдет, если в JSON будет больше параметров книги, которые не поместятся в виде параметров в один метод createBook()? А что насчет этого:

Есть множество других вариантов. Но главное заключается в том, что данные никогда не выходят за пределы объекта book. После создания объекта данные не видны и не доступны никому другому. Мы можем только попросить объект сохранить себя или распечатать себя на какой-либо носитель, но мы никогда не получим данные от него.

Сама идея DTO неправильна, потому что она превращает объектно-ориентированный код в процедурный код. У нас есть процедуры, которые манипулируют данными, и DTO - это просто контейнер для этих данных. Не думайте об этом так и не делайте так.

P.S. Есть несколько других названий для DTO: бизнес-объекты, объекты домена (не в DDD), объекты-сущности, JavaBeans.

Translated by ChatGPT gpt-3.5-turbo/42 on 2023-12-27 at 04:47

sixnines availability badge   GitHub stars