first-programmer
@first-programmer
Backend software engineer

Что может содержать DTO?

Всем привет!

Недавно был дискус с коллегами по поводу того, что может содержать DTO и на сколько он должен быть чистым? Я и еще один коллега придерживаемся мнения, что DTO хоть и не должен содержать логики, но вполне может иметь метод для трансформации данных, например getFromArray. А наш тимлид, человек несомненно более опытный, говорит, что DTO должен быть максимально чистым. Почему я в этом сомневаюсь, потому что мне кажется что излишняя чистота DTO влечет слишком много гемора, что тоже не очень удобно и полезно с точки зрения поддержки кода.

Предположим, у нас приходит некий json мы его декодируем в объект или массив, потом хотим на основе него построить DTO. При этом пусть его структура будет вложенной, допустим пользователь, его профиль и массив некоторой информации дополнительной data.

{
    “guid” : “ someValue”,
    “name”: “ someValue”,
    “phoneNumber”: “ someValue”,
    …
    “userProfile”: {
        “someField”: “someValue"
    },
    “data”: {
         “someField”: “someValue"
    }
}


Хочется просто закинуть данный декодированный объект или массив в метод, dto или в его конструктор, и чтобы он сам построил всю вложенность dto. Без вызова всяких там сетов вручную. При этом вдруг мне еще надо для формирования вложенного dto скажем userProfile использовать еще и данные из уровня выше, допустим захочу телефонный номер закинуть, или мне надо закинуть его именно с плюсом спереди, или сделать любые другие преобразования с данными при построении DTO. Да, можно использовать маппер, но в чем смысл создавать еще и отдельный класс маппера? Что может пойти не так, что DTO от такой логики будет уже не DTO и какие могут быть проблемы?

Я в защиту смог только привете такой пример - до определенного момента в php вообще не было type hints и если мы делали DTO, то как правило был базовый класс, который содержал методы валидация входных данных на основе док блоков. Получается это были какие-то кривые DTO раньше?

Просто мне кажется, что все эти вот правила это на уровне рекомендаций, какие-то обоснованные, какие-то не очень. Нет, понятно что не стоит пихать в DTO бизнес логику, типа там отправку запросов, сохранение в базу данных и прочее. Но мне кажется DTO лучше быть самодостаточным в плане формирования данных, которые он будет хранить. Выглядит лучше чем мапперы с вызовами сеттеров, созданием всей этой цепочки вложенности. Или типа это уже из разряда объект формирует сам себя? А в случае с старым подходом без типов, это еще и валидация, а значит еще нарушение принципа единственной отвественности?

Кто что думает по этому поводу и как формирует DTO?
  • Вопрос задан
  • 334 просмотра
Пригласить эксперта
Ответы на вопрос 4
index0h
@index0h
PHP, Golang. https://github.com/index0h
Dto - data transfer object, его задача - это передать данные. Ваш тимлид говорит верно, дто не должен содержать ничего другого кроме данных и тайпхинтинга.

Json у вас получится в какой-то точке кода, вероятно взаимодействующей с внешним миром: хттп, бд, файлы и т.д. вот именно в этой точке вам и следует делать пасинг и наполнение вашего дто
Ответ написан
Комментировать
AleksandrB
@AleksandrB
Совсем недавно вывел "Hello world"
Я считаю, что может (можно сюда еще)

Логика простая - DTO не может содержать бизнес логики. DTO используется для переброски данных между слоями, сериализацияне является бизнес поведением, это просто разные способы представления плоской структуры данных. Самое главное что бы в сериализации не происходила трансформация. Это может являться частью логики. А делать отдельный класс для каждого дто для сериализации - слишком запарно.

Лично я использую сериализацию в dto.
Ответ написан
Комментировать
ThunderCat
@ThunderCat Куратор тега PHP
{PHP, MySql, HTML, JS, CSS} developer
Что может пойти не так, что DTO от такой логики будет уже не DTO и какие могут быть проблемы?
DTO - чисто инструмент переноса, в классическом ООП он выполняет роль сигнала для взаимодействия между абстрактными сущностями. По этому его задача хранить данные, а логика его построения должна быть отделена. Если у вас 10 дтошек, и что-то поменялось в логике построения, вы будете все десять штук менять, что уже выглядит странно и не очень логично. Напрашивается логичное решение - использовать фэктори, которая, в противовес дто, имеет только логику, и все манипуляции с данными сводятся в 1 место. Пишете фэктори, и на каждый источник у вас свой фабричный метод, а на выходе нужный дто.
Ответ написан
Комментировать
@Vitsliputsli
1) Цель использования DTO - это передать данные между двумя подсистемами. Причем, либо между ними нельзя передать поведение, либо мы хотим, чтобы они были независимы, а передача поведения увеличит зацепление.
2) DTO - это специфика Java, там, объединить разнородные данные можно только в объекте. Поэтому был введен данный механизм - объект с искусственным ограничением, только данные и никакого поведения. Но, php не Java, здесь разнородные данные можно легко объединить в обычном массиве. Вы можете, конечно, массив завернуть в объект, но смысла в этом нет, т.к. мы передаем данные между независимыми подсистемами, ни одна из них не должна быть зацеплена на объекты другой.
3) Как уже написали, сам DTO и механизм его формирующий - это разные вещи, подсистемы могут вообще на разных языках быть написаны, и все будет прекрасно работать, т.к. мы передаем только данные, а не поведение. Если же хочется туда запихнуть валидацию или иное поведение, стоит задуматься, а зачем здесь DTO? Не проще ли тогда сразу передавать полноценный объект.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
19 апр. 2024, в 05:01
999999 руб./за проект
19 апр. 2024, в 03:52
1000 руб./за проект
19 апр. 2024, в 03:01
1000 руб./за проект