В чем разница между DTO vs ValueObject vs Entity на примерах? Правильное именование классов.

Yoskaldyr

"Спамер"
Партнер клуба
В общем сабж. Интересует в контексте именно PHP и в контексте применения вместе с DataMapper-ом.
Сколько логики хранить в этих объектах и хранить ли вообще.
Спрашиваю потому что в сети общие определения этих терминов если и можно найти более менее одинаковые, то детали реализации уж очень у всех отличаются.
Например, в идеале ValueObject должен быть иммутабельный, но если очень хочется то можно модифицировать. Если его модифицировать то возвращать клон объекта, но если очень хочется можно модифицировать данные напрямую.
Одни считают что логики в DTO совсем не должно быть, другие считают что если очень хочется то можно.
Насчет Entity вообще не понятно - каждый понимает под Entity вообще что угодно.

Т.е. термины как-бы и есть но каждый их понимает по своему в пхп сообществе.

Теперь практическая задача
Пусть для примера это будет сферический конь в вакууме - сообщение форума
У которого есть
post_id
user_id
thread_id
message
created_at
modified_at

Т.е. по каким классам разнести методы получения из базы /сохранение в базу 1 поста, различные методы проверки возможности просмотра, редактирования и др., методы преобразования полей поста (форматирование даты, автоцензор) и т.д., методы работы с коллекциями постов (получение/обновлени коллекции) и как их назвать?

По каким классам разнести данные и логику если я хочу использовать датамеппер для сохранения и тоже как назвать эти классы? Что на входе должен получать датамеппер?
 

fixxxer

К.О.
Партнер клуба
Определения есть у Эванса, так что проще по признакам.

Entity - мутабелен, сущность при этом идентифицируется обычно одним полем или небольшим их набором, скажем, id, или email, или login + domain.

PHP:
class Entity implements IEquatable {
    public function equals(Entity $other) {
        return $this->id == $other->id;
    }
}
ValueObject же равны, если равны все их поля, и понятие уникальности к ним неприменимо.

DTO - это несколько "из другой серии", они для обмена данными, можно сказать, что это просто структура. Логики там в идеале быть не должно, но бывает, что делают implements Arrayable/Jsonable, чтобы не связываться с reflection, не вижу в этом ничего страшного.
 

Yoskaldyr

"Спамер"
Партнер клуба
@fixxxer, тогда что должен принимать/возвращать датамеппер при записи/извлечении данных из базы - Entity или VO ?
 

Yoskaldyr

"Спамер"
Партнер клуба
@AnrDaemon, Да просто хочу разобраться в принципе. Потому что если смотреть готовые реализации датамепперов и варианты использования этих датамепперов, то в деталях они сильно различаются и какой вариант более правильный - я хз.
Например в некоторых на вход датамепперу можно вообще что угодно подать, что массив, что Entity, что VO, но как мне кажется это не сильно хорошо пахнет.

Может есть какой-то реальный пример нормального живого проекта с использованием датамеппера с нормальным именованием классов с правильным распределением логики по классам (т.е. какая логика в Entity, какая в DM)?

P.S. Вариант данных выше привел для примера (хотя в реальном проекте в таблице значительно больше колонок).
 

AnrDaemon

Продвинутый новичок
Да нет этого "более правильного". Есть более подходящий под конкретную задачу.
 

Yoskaldyr

"Спамер"
Партнер клуба
Да нет этого "более правильного". Есть более подходящий под конкретную задачу.
Задача описана выше.

Переформулирую вопрос - есть где в паблике примеры грамотного использования Data Mappers + Repository на php? Понятно что у всех есть куча закрытых проектов которые нельзя показать из-за NDA, но может кто-то где-то видел хорошую реализацию?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
:D вчера, в пятницу, после рабочего дня, часов так до 9 вечера, в Oracle два уставших руководителя обсуждали со мной такие глубокие философские темы, как "Что такое система?", "Что такое структура?". Причем, без пива!
Я даже провел аналогию с чашечностью чаши, как у Аристотеля, но мне показалось, что они не знакомы с античной метафизикой.
Меня такие темы раздражают. Дальше, закономерно, был вопрос "как на PHP быстрее всего посчитать количество единиц в бинарном представлении строки?"

Нет никакой ложки. Нет контекста PHP. Нет "своего понимания" и "грамотного решения". Есть задача, есть множество решений, и есть бритва Оккама.
Если ты понимаешь зачем в этой задаче нужна неизменность - сделай ее. Не добавляй неизменность туда, где оно не нужно.
Пиши код, #$%.
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
@fixxxer, тогда что должен принимать/возвращать датамеппер при записи/извлечении данных из базы - Entity или VO ?
Aggregate root entity, как правило.

Судя по вопросам, Эванса не читал толком. :)

Почитай хотя бы Domain Driven Design Quickly, там все то же самое, только изложено более компактно, без разжевывания.
 

AmdY

Пью пиво
Команда форума
знаешь, я просто поражаюсь такой фигне, люди пишут 100500 лишних слоёв, отказываются от плюшек баз данных. А по итогу в коде не могут даже с зависимости управиться и гет-сет нормальные прописать.
https://github.com/leopro/trip-planner/blob/master/src/Leopro/TripPlanner/Domain/Entity/Leg.php#L25
https://github.com/leopro/trip-planner/blob/master/src/Leopro/TripPlanner/Domain/Entity/Location.php#L24
https://github.com/leopro/trip-planner/blob/master/src/Leopro/TripPlanner/Domain/Entity/Route.php#L34
вот такие прекрасные цепочки вызовов строят
https://github.com/leopro/trip-planner/blob/master/src/Leopro/TripPlanner/Domain/Entity/Route.php#L54

хотя здесь сет нормальный, а не if (valid) $this->memberId = ....
https://github.com/leopro/trip-planner/blob/master/src/Leopro/TripPlanner/Domain/Entity/Trip.php#L29

насколько же код становится проще и лешче поддерживать от такого вот треша?
https://github.com/leopro/trip-planner/blob/master/src/Leopro/TripPlanner/Application/Command/AddLegToRouteCommand.php
 

Yoskaldyr

"Спамер"
Партнер клуба
Почитай хотя бы Domain Driven Design Quickly, там все то же самое, только изложено более компактно, без разжевывания.
Именно то что надо - ответ сразу получил прочитав пару страниц посвященных VO и Entity. Плюс очень хороший пример приложения выше в плане разделения логики.
 

fixxxer

К.О.
Партнер клуба
@AmdY, ну как тебе сказать, там местами спорно, но это нюансы мало относящиеся к сути, а так другого вменяемого примера я на php не видел. Касаемо command - задача проекта продемонстрировать каноничный подход, в таком виде конечно смысла мало на практике, но это вообще проблема "учебных" проектов, вечно "hello world на паттернах" получается.

А с иронией и сарказмом у меня сегодня плохо, в тред призывается Вурдалак. :)
 

Вурдалак

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

grigori

( ͡° ͜ʖ ͡°)
Команда форума
А как можно обрабатывать VO если он иммутабельный? Обработка подразумевает изменение/модификацию
Давай говорить конкретно. VO удобен, к примеру, для хранения состояния окружения или параметров вызова.
Например, у меня форма со связанными полями. Прогоняю $_POST через filter_array_var, добавляю текущее время - получаю Value Object, отфильтрованные данные с гарантированной корректностью синтаксиса. Затем отдаю его в модель, которая обрабатывает данные.
А еще у меня есть тесты. Я создаю ValueObject, заполняю данными, и для разных проверок меняю данные в VO.

Другой пример - подготовленные данные для передачи по сети. Это DTO, который генерируется моделью для использования в curl_setopt().
 
Последнее редактирование:

AmdY

Пью пиво
Команда форума
@AmdY, ты как пенсионер от программирования, уже не способен воспринимать что-то новое и это вызывает у тебя только раздражение. К счастью, мир не крутится вокруг твоего белорусского пива и ценности разные, под разные проекты требуются разные подходы.
Ты путаешь, с какого это новое? DDD сто лет в обед, не говоря уже о том, что это продолжение MVC. Беда в том, что сейчас его начали превращать в серебряную пулю в то время как основы вроде инверсии зависимостей не осознали и хардкодят такое гавно и считают что это будет легко поддерживать. Чтобы не быть голословным ссылки привел.

Нормальный человек делает декомпозицию, разбирается с зависимостями и отвественостями и получает своё DDD, при этом руководствуется здравым смыслом, а не пыльной книгой Эванса. Тот же иммутэйбл в VO в php который крутится в 100500 процессах на десятках серверов, да не смешите.
 
Сверху