я понял, наконец

Adelf

Administrator
Команда форума
Сильно усложнять - да. Но это же не значит что надо вообще отказываться от методов.
Можно и не отказываться, но лучше, чтобы их можно было бы реализовать внешне. Как, например, методы-расширения в C# или Kotlin. Прежде всего дтошка - это хранилище данных. там не место полиморфизмам и инкапсуляциям
 

AmdY

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

Это файлеровский value object может иметь специфичную для типа логику.
 

Yoskaldyr

"Спамер"
Партнер клуба
@Adelf @AmdY ну тогда можно вообще откатиться на процедурщину.
транспорт между приложениями это Json, CSV и т.п., DTO - это представление данных внутри приложения и в нем логично иметь toArray, toJson, toCSV как написал @grigori
 

fixxxer

К.О.
Партнер клуба
При чем тут процедурщина? DTO - это просто структура. Adelf правильно заметил, что примерно как аргументы метода.

Ты же пишешь $foo->method($parameter), а не $parameter->execute($foo, 'method')?

С чего бы структуре знать, во что ее сериализовывать? Сериализация относится к конкретному протоколу обмена данными, а не к самой структуре. DTO с toJson() - это тот же ActiveRecord, вид сбоку: как обязанностью модели не является персистить себя в базу, так и обязанностью DTO не является сериализовывать себя в какой-нибудь json.
 

whirlwind

TDD infected, paranoid
С чего бы структуре знать, во что ее сериализовывать?
С языка снял. Вспоминаем OSI

PS. Единственное во что должен сериализоваться DTO это в string, что бы при фейле assertEquals выдавал нечто более понятное нежели код типа с произвольным хэшем.
 

fixxxer

К.О.
Партнер клуба
Единственное во что должен сериализоваться DTO это в string, что бы при фейле assertEquals выдавал нечто более понятное нежели код типа с произвольным хэшем.
Я бы не назвал это в общем случае полноценной сериализацией. Сериализация подразумевает возможность десериализации, а тут это совершенно необязательно, достаточно, чтобы был понятен контекст (да и нежелательно, если там внутри, например, string на пару мегабайт).

Да и от testing фреймворка зависит, он вполне может через reflection выдавать что-то приемлемое.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
1. fixxxer придумал понятие "неполноценный объект", и я с этим определением не согласен - это полноценный объект
2. про наследование речи нет, оно тут ни при чем
3. сравнивать язык программирования с протоколом обмена данными и сетевой моделью - давайте его еще взвесим, уже не знаете что высосать из пальца
4. кто считает наоборот, кроме меня - открываем доки или примеры по всем фреймвокам и ищем ваш DTO как структуру без методов.
У этого автора DTO даже втягивает данные в себя из другого объекта.
как суслик - никто не видит, а вы знаете, что он есть! :)
 
Последнее редактирование:

grigori

( ͡° ͜ʖ ͡°)
Команда форума
При чем тут процедурщина? DTO - это просто структура. Adelf правильно заметил, что примерно как аргументы метода.
Ты же пишешь $foo->method($parameter), а не $parameter->execute($foo, 'method')?
Я писал про Value Object. DTO - это относительно неустоявшееся понятие, но ты их уравнял в первом тезисе, так что все-таки это фантазия.

процедурщина - это как-раз namespace\foo(data), но не синтаксис делает код объектым.
С чего бы структуре знать, во что ее сериализовывать? Сериализация относится к конкретному протоколу обмена данными, а не к самой структуре. DTO с toJson() - это тот же ActiveRecord, вид сбоку: как обязанностью модели не является персистить себя в базу, так и обязанностью DTO не является сериализовывать себя в какой-нибудь json.
ага, и тут же начинается: только для ...
а почему не массив-то? зачем эти телодвижения, структура - это массив
DTO - это не просто аргумент, он может гарантировать целостность своей структуры, это живой объект, а не любые данные
 
Последнее редактирование:

Adelf

Administrator
Команда форума
DTO - это не просто аргумент, он может гарантировать целостность своей структуры, это живой объект, а не любые данные
Видимо, ты немного попутал VO и DTO. Ладно, забудем про кидание ДТОшками по сети. Давай попробуем на простом примере. У нас есть некоторая команда, и допустим от пользователя требуется ввести либо email, либо телефон. обязательно что-то одно должно быть. Соответственно, если следовать твоей логике, у нас будет ДТО(Email|null $email, Phone|null $phone, куча других полей) и это ДТО будет следить, чтобы хотя бы одно из них было не null. Это ведь "гарантирует целостность"?
Но тут как раз напрашивается VO - UserContact(Email|null $email, Phone|null $phone),с которым ещё и дальше будем работать и ДТО будет содержать (UserContact $contact, другие поля). VO потому, что в данном случае оно является отдельным объектом с логикой. В любом месте, где у тебя поля ДТО начинают иметь общую логику, там напрашивается VO. Не должно быть ДТО с $x, $y координатами, должно быть ДТО с полем Point. Не должно быть DTO с пятью полями про адрес и "гарантирующее целостность" себя. Должно быть ДТО с полем Address $address.
Поэтому, не должно быть никаких "гарантировать целостность своей структуры" от ДТО. ДТО это просто набор полей, которые в свою очередь уже могут "гарантировать целостность своей структуры". Прямая аналогия с параметрами функции. А то, что вы тут увидели процедурное программирование, меня вообще удивило )
 

MiksIr

miksir@home:~$
> кто считает наоборот, кроме меня - открываем доки или примеры по всем фреймвокам и ищем ваш DTO как структуру без методов.
Предлагаю калибровать значение термина DTO из первоисточника. https://martinfowler.com/eaaCatalog/dataTransferObject.html

> Не должно быть DTO с пятью полями про адрес и "гарантирующее целостность" себя. Должно быть ДТО с полем Address $address.
Кому должно? Никому DTO ничего не должно. Он должно уметь сериализовать и десериализовать. Если это не LocalDTO.

> а почему не массив-то? зачем эти телодвижения, структура - это массив
В целом да, хешмап может быть заменой LocalDTO, но в большинстве случаев это просто не удобно. Во-первых, банально с кодом не удобно работать, а во вторых - непонятно, где находится тот код, который создал этот массив на основе доменной модели.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
>Если это не LocalDTO.
Радует, что мы начали использовать оригинальные определения, предлагаю не продолжать придумывать термины.

>банально с кодом не удобно работать
а сишники в php оборачивают функции в классы для автолоада, и это не имеет отношения к дизайну

@Adelf многими людьми в мире java эти термины VO и TO используются как взаимозаменяемые

Под целостностью я имею ввиду возможность VO проверить при создании, что все обязательные поля заполнены, посчитать по себе хеш и количество элементов. Без нарушения инкапсуляции - только операции, связанные с передачей, каким-то форматированием и контролем.

Можно ли считать объект image magic VO или DTO со всеми его операциями по преобразованию картинки?
 

fixxxer

К.О.
Партнер клуба
Предлагаю калибровать значение термина DTO из первоисточника. https://martinfowler.com/eaaCatalog/dataTransferObject.html
Тут речь идет о DTO, который трансферится между Java-приложениями, со стандартным Java serialize. В те времена, когда писался PoEAA, это выглядело уместным. Пофигу что там в сериализованной строке, просто передали туда-сюда и все, Java сама разберется. Относительно PHP можно сказать, что это должен быть объект, которому мы можем безопасно сделать serialize() и unserialize().

Сейчас же в мире докеров и k8s мы обмениваемся данными между микросервисами, написанными на разных языках с совершенно разными типами данных. Где-то json-ами, где-то msgpack-ами, где-то протобуфами. Появился контекст этой самой сериализации, который относится не к самой структуре данных, а к транспортному протоколу. Как верно заметил whirlwind
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Тут речь идет о DTO, который трансферится между Java-приложениями, со стандартным Java serialize. В те времена, когда писался PoEAA, это выглядело уместным.
Относительно PHP можно сказать, что это должен быть объект, которому ...
библию еще не толкуешь?
 
Последнее редактирование:

grigori

( ͡° ͜ʖ ͡°)
Команда форума
это песня

1. взяли паттерн для передачи данных по сети,
2. придумали идею о том, что для передачи данных из объекта в объект по ссылке без копирования в оперативной памяти надо оформлять в пустом классе с публичными полямибез методов
3. назвали свою идею по имени известного паттерна
4. вспомнили OSI-модель сети, транспортный протокол и kubernetes
:) как это вообще связано?
 

AmdY

Пью пиво
Команда форума
> кто считает наоборот, кроме меня - открываем доки или примеры по всем фреймвокам и ищем ваш DTO как структуру без методов.
Предлагаю калибровать значение термина DTO из первоисточника. https://martinfowler.com/eaaCatalog/dataTransferObject.html
Вот в этом источнике и кроется суть проблемы,
Many people in the Sun community use the term "Value Object" for this pattern. I use it to mean something else. See the discussion on page 487.
Отсюда и путаница. Да и с логической точки зрения, зачем в транспорт таскать все сериализаторы, получается что DTO должна знать куда её будут совать, что бредово с архитектурной точки зрения.
 

MiksIr

miksir@home:~$
Да и с логической точки зрения, зачем в транспорт таскать все сериализаторы, получается что DTO должна знать куда её будут совать, что бредово с архитектурной точки зрения.
Так DTO и есть часть транспорта. Есть данные, которые вы хотите отправить, есть их сериализация, есть отправка. Какое тут уникальное место для DTO? Да никакого, по сути это часть сериализации. И да, DTO может знать, как себя сериализовать в xml, как json, а как в проприетарный бинарный протокол. Ибо, внезапно, оказывается, что могут быть нюансы как сериализовать то или иное поле в xml, а как в json, и если не рассматривать DTO как сериализатор, то сверху начинают накатывать конфиги, аннотации и прочее, что бы именно этот сериализатор именно это DTO сериализовал именно, так, а другое DTO иначе.
 

MiksIr

miksir@home:~$
Сейчас же в мире докеров и k8s мы обмениваемся данными между микросервисами, написанными на разных языках с совершенно разными типами данных. Где-то json-ами, где-то msgpack-ами, где-то протобуфами. Появился контекст этой самой сериализации, который относится не к самой структуре данных, а к транспортному протоколу.
И опять же, ничто не мешает DTO знать эти нюансы, ибо DTO - часть транспорта. Попытка отделить структуру предназначенную для передачи по конкретному транспорту от этого транспорта выглядит не очень обоснованно. Ты уверен, что сможешь с помощью контекста решить оптимально передачу одного и того же DTO разными протоколами? Я вот не уверен, а значит предполагаю появление в контексте какой-то кастомной конфигурации для конкретного DTO... зачем? Что мы этим добились то?
 

fixxxer

К.О.
Партнер клуба
часть транспорта
А HTTP-запрос тоже DTO должен отправлять? Или в AMQP-очередь себя добавлять?
DTO может знать, как себя сериализовать в xml, как json, а как в проприетарный бинарный протокол
А модель может знать, как записать себя в MySQL, PostgreSQL или MongoDB.
что могут быть нюансы
Конечно. А еще могут быть нюансы, как какое поле сохранить в MySQL или PostgreSQL. Нерешамая проблема без Active Record!
начинают накатывать конфиги
Да. Конфиг маппинга.

Ты так говоришь, как будто это что-то плохое.
 
Сверху