Domain Driven Design - просто о сложном. Дмитрий Науменко.

  Рет қаралды 66,138

Съесть Собаку

Съесть Собаку

7 жыл бұрын

Доклад Дмитрия Науменко на Съесть собаку #8. PHP. 20/04/17
Для всех участников восьмой встречи “Съесть собаку” и наших подписчиков Дима собрал список из 4 ресурсов и книг, которые точно пригодятся в работе.
1. Книга «Domain-Driven Design: Tackling Complexity in the Heart of Software» Эрика Эванса: www.amazon.com/Domain-Driven-...
Очень рекомендую к прочтению. Книга об организации и систематизации принципов построения логической структуры предметной области.
2. Книга «Domain Driven Design Quickly» Эйбла Аврама и Флойда Маринеску: www.infoq.com/minibooks/domai...
По сути, эта книга кратко пересказывает то, о чем писал Эрик Эванс в «DDD».
3. Книга Гради Буч «Объектно-ориентированный анализ и проектирование с примерами приложений на С++ »: www.helloworld.ru/texts/comp/o...
Хорошо описана теория и практичные советы, касающиеся вопросов анализа, проектирования, реализации и оптимального управления проектами.
4. Uncle Bob. The Clean Architecture: 8thlight.com/blog/uncle-bob/2...
Кратко почитать о правилах построения чистой архитектуры в блоге Роберта Мартина.

Пікірлер: 95
@user-ro7nf1ec8h
@user-ro7nf1ec8h 7 жыл бұрын
Прекрасный доклад и интересные вопросы к нему. Спасибо
@vadymradvansky1569
@vadymradvansky1569 3 жыл бұрын
DTO используется для передачи данных между слоями. Ок. Пример "AddressDto" имеет метод "fromRequest". В каком слое должен тогда лежать такой DTO? Если его положить в слой контроллеров, то получается слои, расположенные ниже, будут знать о DTO из уровня контроллеров (фактически слоя инфраструктуры раз мы уже знаем о реквесте). Если его положить в какой то слой ниже, то слой ниже должен знать о деталях имплементации слоя выше включая как именно данные будут передаваться (POST). То есть если мы надумаем передавать данные через GET, то изменения затронут не только уровень инфраструктуры, а и уровень апликейшена (доменных сервисов). Я думаю правильная имплементация подобного DTO должна содержать только метод "load(array $data)", а использоваться в контроллере "(new AddressDto())->load($request->post())".
@vlad_covers
@vlad_covers 9 ай бұрын
Сам по себе метод fromRequest указывает на вышележащий request. Возможно, имеет смысл отвалидировать request->post и передать в Dto аргументы по-отдельности (country, city, zip и lines).
@vadymradvansky1569
@vadymradvansky1569 9 ай бұрын
@@vlad_covers На самом деле DTO НЕ используется для передачи данных между слоями. Такой подход называется "local DTO" и является антипатерном. Докладчик просто этого не знал. DTO используется для передачи данных между сервисами, хороший примером является gRPC. Дальше на уровне транспортейшн лейера DTO конвертируется во внутренние какие то данные, а DTO выбрасывается. "и передать в Dto аргументы по-отдельности (country, city, zip и lines)" - это правильно.
@vlad_covers
@vlad_covers 9 ай бұрын
@@vadymradvansky1569 Вадим, благодарю за развёрнутое уточнение! 🙏
@ejoys3
@ejoys3 6 ай бұрын
@@vadymradvansky1569 Используется. На то он и Transfer Object. Хранится он в том слое который получает данные.. например в UseCase это Command или Query которая лежит рядом с handler.. или ServiceActionNameDTO если это сервисы, которые инстенсит контроллер.. слои ниже ничего не знают (не должны) о реквесте, а получают все необходимое через DTO или как параметры вызова.
@osad4enko
@osad4enko 2 ай бұрын
в домене положить interface IAddress и при создании класса AddressDto implements IAddress
@maxvanyushkin6609
@maxvanyushkin6609 3 жыл бұрын
Спасибо, Дмитрий. все коротко и по делу, без лишней воды.
@andreyklochok
@andreyklochok 5 жыл бұрын
Отличный доклад, спасибо!
@dmitrygladkikh8230
@dmitrygladkikh8230 6 жыл бұрын
Очень доходчиво. Спасибо!
@aleksei4604
@aleksei4604 3 жыл бұрын
Очень хороший доклад!
@antonpanton7460
@antonpanton7460 4 жыл бұрын
Спасибо, очень просто и понятно!
@atomicru
@atomicru 7 жыл бұрын
Хорошее введение в DDD. Спасибо за доклад!
@vitalyalyokhin3411
@vitalyalyokhin3411 5 жыл бұрын
Оператору незачёт, докладчик крупным планом, код издалека - ничего не разобрать.
@user-dk5wz4vd6r
@user-dk5wz4vd6r Жыл бұрын
Лучший доклад по ддд что я видел !!!
@kuvshinovee
@kuvshinovee 7 жыл бұрын
отличные вопросы и нормальный доклад
@mqhamdam
@mqhamdam 2 жыл бұрын
докладчик хорош не идеал и видно что волнуется но старается ! А второму челу который задал вопрос, хочется сказать научись задавать вопросы и думай что там человек тоже волнуется. А третьи чел задавал крутые вопросы и правильно их задавал спасибо ему !
@zond_amond
@zond_amond 2 жыл бұрын
Хотел бы выступить в защиту докладчика. Третий чел протупил в своем первом вопросе, он предъявляет претензию, что раз заказчик не владеет техникой DDD, не пользуется единым языком.и пр., то это значит, что зря разработчики взяли ее за основу и что они ее не используют. А что, они должны провести семинары для заказчиков, или все-таки кодить должны? Он предлагает сменить заказчиков на более умных? А им это понравится? Это бизнес, в нем надо подстраиваться под желания и возможности бизнеса, а не пальцы гнуть.
@user-tu7bt9ye4u
@user-tu7bt9ye4u 2 жыл бұрын
@@zond_amond , задававший вопрос совсем не это имел ввиду, а то что разработчики должны подстраиваться под заказчиков (так как наоборот невозможно сделать =)), об этом как раз и гласит основополагающая идея Ubiquitous Language (единая терминология) в DDD, и он своим вопросом намекнул, что мол докладчик использует DDD без его основной идеи, а соответственно можно сделать вывод что это не DDD, а пародия. P.S. смотрел видос и думал как же просто и понятно объясняет докладчик, а потом услышав вопросы этого самого чела - мое мнение реверсивно изменилось, так как я понял, что в его докладе лишь имитация DDD.
@zond_amond
@zond_amond 2 жыл бұрын
@@user-tu7bt9ye4u а ты посмотри видео этого чела, который задает этот вопрос. У нас все наоборот устроено на 180 градусов. Услышал у него в том числе сказочные истории про то, как он обычно указывает бизнесу свои требования.
@1kit
@1kit 3 жыл бұрын
В конце понравилось что меня раскусили. Попробовал смотреть на 1.75 и решил что хочу кайфануть, потому 1.25 использовал. Немного триггерило слово итем. :) Но со временем смирился с таким вариантом, будем считать это частью диалекта. :) Лайк тебе за доклад.
@magnumataredfox
@magnumataredfox 2 жыл бұрын
Очень интересно, но нет последовательности, вначале говорилось что Client это Entity, потом он вдруг стал агрегатом? Что за?
@maksimepikhin
@maksimepikhin 2 жыл бұрын
А можно будет все эти примеры как-то посмотреть текстом, если есть?
@MrLevelweb
@MrLevelweb 6 жыл бұрын
Как зовут гения, который много лет использует DDD, задает интересные вопросы по взаимодействию с заказчиком и одет в черное?
@ivankalayanov1263
@ivankalayanov1263 5 жыл бұрын
kzbin.info/www/bejne/lXSuZn6XnJyYpNk
@djoutline
@djoutline 4 жыл бұрын
Эрик
@namesecondname663
@namesecondname663 4 жыл бұрын
Мартин Фаулер
@rtcw1984
@rtcw1984 4 жыл бұрын
Чарльз Бэббидж
@MrLevelweb
@MrLevelweb 4 жыл бұрын
Елена Беркова
@failure232
@failure232 3 жыл бұрын
Поделитесь, пожалуйста, ссылкой на презентацию
@kinordikus
@kinordikus 3 жыл бұрын
Самое адекватное объяснение DDD, на мой взгляд.
@SiteBizzona
@SiteBizzona 4 жыл бұрын
Хорошая подача материала, но есть один момент интересный, рассматривались простые action и использование в них сервисов, но как поступить в случае, когда есть просто action для вывода gridview и внутри этого action необходимо отдать на view dataProvider - в таком случае если делать сервис, который делает выборку данных и отдает затем ActiveDataProvider немножко выглядит странным. Этот вопрос из серии когда толстый контроллер пробую сделать тонким через сервис. return $this->render('index', [ 'dataProvider' => $this->serviceData->getActiveDataProvider(), ................. public function getActiveDataProvider() : ActiveDataProvider { $dataProvider = new ActiveDataProvider([ 'query' => $this->getData(), ]); return $dataProvider; }
@a.batorsky
@a.batorsky 2 ай бұрын
4:53 Вопросы: - почему связи задом-наперед; - почему клиент не может существовать без счета; - почему у клиента не определены типы данных. Стоит ли смотреть дальше?
@itcloudguy
@itcloudguy 3 ай бұрын
47:40 - В 2017-м поисковых систем не было по-моему ещё, если не ошибаюсь... GPT уж точно не было чтоб спросить о разнице (как 2024-м). :)
@user-lf1ep5io7r
@user-lf1ep5io7r Жыл бұрын
У вас на UML диаграмме направление отношения агрегации неверное
@user-tu7bt9ye4u
@user-tu7bt9ye4u 2 жыл бұрын
хороший доклад, но объясняет лишь часть подхода DDD. Тот чел, который в конце доклада задавал вопросы про основополагающие идеи DDD прям в точку бил, ведь в примере доклада они никак не представлены
@iashumov
@iashumov 5 жыл бұрын
Меня одного смутило на 4:54 что UML не верно записан и направление агрегации и композиции обратное?
@kovalenkoihor4325
@kovalenkoihor4325 5 жыл бұрын
Я на этом моменте пошел в гугл перепроверил что я правильно помню в какую сторону стрелки рисуются )))
@iashumov
@iashumov 5 жыл бұрын
Вот и я так же. Нельзя так пугать людей
@alexandrdeveloper1242
@alexandrdeveloper1242 4 жыл бұрын
Блин, а я то всё думал, что меня в этой картинке раздражает..
@epuremath
@epuremath 3 жыл бұрын
не, не тебя одного. но по uml тоже хороших докладчиков не хватает...
@iashumov
@iashumov 3 жыл бұрын
@@epuremath ну а что быть докладчиком по тому что во-первых не меняется поколениями, а во-вторых не имеет реального применения? Почти всегда используются semi-formal виды
@fife3366
@fife3366 2 жыл бұрын
четко!
@BogdanDotPy
@BogdanDotPy 8 ай бұрын
я так и не понял, DDD это просто набор шаблонов и советов которые можно применять как душе угодно?
@mclotos
@mclotos 5 жыл бұрын
Всё супер, но мне не понятно если например у нас тот же самый Client или Item понадобится где-то в другом домене, вот так получилось что структура класса Client для этого домена такая же как и у другого домена, копипастить? И по поводу независимости домена от базы данных и неизменяемости VO. Предполагается что при инициализации домена, мы уже передали в него всю необходимую информацию и на время работы с доменом вообще не обращаемся к базе данных? И если Position это Entity, то почему у него нет идентификатора?
@nikitagusev2215
@nikitagusev2215 5 жыл бұрын
Ну по сути да, копипастить. Предполагается, что разные контексты общаются друг с другом через Domain Events. Домен Client'а просто посылает событие, а кто его обработает в другом домене его совершенно не должно волновать. Про инициализацию домена... Да, агрегат лучше сразу инициализировать. Но не надо по каждому случаю создавать агрегат, например, при вытаскивании из базы 50 записей не нужно доставать 50 агрегатов. Ну и сами агрегаты не стоит делать слишком большими. Я имею исключительно негативный опыт DDD на реальных проектах, но рекомендую почитать статьи и книги Vaughn Vernon'а. Оригинальная концепция DDD сильно недоработанная, Vernon многие подобные практические вопросы пытается прояснить.
@mclotos
@mclotos 5 жыл бұрын
@@nikitagusev2215 пересматривал и заметил еще один момент - Position у него Entity, но при этом в классе Position нет свойства для идентификатора, получается что это не Entity, а Agregate, так как свои идентификаторы есть только у Item, которые внутри Position или я что-то не так понял?
@nikitagusev2215
@nikitagusev2215 5 жыл бұрын
Не помню про position. Но вообще агрегат это корневой entity, то есть идентификатор у агрегатов должен быть. Поищите статьи Effective aggregate design by Vaughn Vernon.
@vadymradvansky1569
@vadymradvansky1569 3 жыл бұрын
@@mclotos У агрегата есть айди также как и у Entity. А если айди нет, то это Value Object.
@user-mt9bq2xe1z
@user-mt9bq2xe1z 3 жыл бұрын
Крутой доклад. А value-object и DTO это ведь одно и то же?
@sergegindin1658
@sergegindin1658 2 жыл бұрын
нет это разные вещи, DTO не содержит логики и может быть мутабельным (теоретически) VO - не изменяемые и могут содержать поведение
@MrRomanvideo
@MrRomanvideo 2 жыл бұрын
А может делать скидки через паттерн декоратор?
@resolution07
@resolution07 5 ай бұрын
Не совсем понимаю как это можно сделать через декоратор. Скидки есть часть бизнес логики - часть бизнес модели. Значит этот механизм должен быть намертво встроен в контексте добавления товара заказ. При каждом добавлении товара должна вызываться операция определения скидки (стратегия) и пересчитываться корзина.
@alexonezashvili554
@alexonezashvili554 4 жыл бұрын
почему у него Poistion это Entity а не агрегат ?
@rugleb
@rugleb 3 жыл бұрын
Тоже непонятно
@dyadya5746
@dyadya5746 3 жыл бұрын
Не совсем понял пример с купюрой. Что значит "криминалист должен различать их по идентификатору"? Что в данной ситуации выступает идентификатором? В том числе и для кассира есть какой-то идентификатор у купюры?
@artem-sobol
@artem-sobol 3 жыл бұрын
На каждой купюре уникальный номер. Помимо этого разный год выпуска, разные подписи глав банка. Да и просто у криминалиста на каждую купюру может быть наклеен стикер с номером дела, к примеру.
@-dubok-
@-dubok- Жыл бұрын
Доклад в чём-то неплохой (в плане теории), но согласен с одним из комментаторов, что вы создали не DDD, а анемичную функциональную модель, а надо было до конца следовать принципам ООП. Почему так? Советую посмотреть видео по ссылке с времени 22.16: kzbin.info/www/bejne/gIDckIaEgJikoJY
@super_mr_unknown
@super_mr_unknown 3 жыл бұрын
Пока не досмотрел до конца, чтобы не забыть задам вопрос - почему Item агрегат, и он входит в состав Entity position? Разве агрегат может входить в состав entity? Вроде агрегат на то и агрегат чтобы агрегировать в себе сущности (entity)?
@sergegindin1658
@sergegindin1658 2 жыл бұрын
Агрегаты не могут входить в состав сущностей, но сущности могут ссылаться на другие агрегаты.
@zond_amond
@zond_amond 2 жыл бұрын
Хороший доклад, только не понравилось что пропущена тема сабдоменов и ограниченного контекста. В данном примере домен выбран неправильно, скорее всего работа со счетом это такой сабдомен. Домен же - это весь бизнес, который содержит в том числе и выставление счета. Чаще всего, но не всегда, домен - это вся деятельность компании в конкретной области. Но я повторю, доклад достаточно хороший и очень подробный!
@vadymradvansky1569
@vadymradvansky1569 3 жыл бұрын
Валидация не должна быть на уровне Entity, потому что это нереально. Допустим надо проверить существует ли имейл в базе. Без запроса в базу это сделать не получится, а Entity не может обращаться напрямую в базу, так как в его слое базы как бы и не существует еще. Невалидные данные в Entity должны вываливать эксепшн, который должен ловить уровень инфраструктуры, логировать его, а девелоперы должны анализировать эти логи, находить как невалидные данные докатились до уровня Entity и править код, что бы этого больше не повторилось. Многослойная валидация - тоже не выход. Это приведет либо к неконсистентным валидационным ошибкам, от которых пользы конечному юзеру будет мало. Либо к тому, что контейнер для валидационных ошибок будет гоняться по куче слоев. Валидироваться должны входящие данные на самом верхнем уровне. Как возможное решение каждый кусок бизнес логики (фактически каждый метод сервиса) должен всегда принимать DTO наполненный волью обджектами, а вот сам DTO должен валидироваться. Если валидация DTO написана неправильно и невалидные данные просочились ниже по слоям - только Exception спасет отца русской демократии, а валидацию DTO нужно улучшить.
@Man6524
@Man6524 3 жыл бұрын
валидация разная бывает, валидировать можно формат данных, тип данных, валидации бизнес логики.
@vadymradvansky1569
@vadymradvansky1569 3 жыл бұрын
Man6524 формат данных - это не валидация. Это в пыхыпы ларавельщики пишут валидаторы типа «маст бы стринг», к валидации это не имеет отношения никакого. Неправильная структура данных - это тоже не валидация. Сначала данные надо привести к нормальному формату и структуре (нормализация), а потом уже валидировать.
@rugleb
@rugleb 3 жыл бұрын
Поэтому надо писать тесты и проблем не будет
@vadymradvansky1569
@vadymradvansky1569 3 жыл бұрын
​@@rugleb "Поэтому" - это к чему относится? Какие именно тесты? Каких проблем не будет? Это о чем вообще было? Здесь как бы не детский сад, все выше описанное подразумевает ситуацию, когда тесты уже написаны. Что снова приводит к выводу, что валидация на уровне Entity - это уже слишком поздно. Потому что Entity как бы тестами напрямую не покрываются, даже не смотря на то, что в них может быть какая то бизнес логика.То есть что бы добраться тестами к валидации в энтити, надо будет влезать через игольное ушко и за этим ушком обнаружить дивный сад, а скорее зоопарк, багов ))).
@rugleb
@rugleb 3 жыл бұрын
@@vadymradvansky1569 если не детский сад, то очевидно, что тесты нужно писать на каждый слой, а не на одну узкую точку входа. По хорошему валидация должна быть тоже на каждом слое, возможно она даже будет отличаться во формату исключений или ещё чём-нибудь. Вы это все тестируете хорошо и никаких проблем, клиент не увидит ошибок, который не должен увидеть. Если для вас это слишком сложно. То доверяйте валидация на самом верхнем слое и внутри делайте вид, что кто-то сверху уже провалидировал.
@alex_chugaev
@alex_chugaev 7 жыл бұрын
Спасибо.
@MrRomanvideo
@MrRomanvideo 2 жыл бұрын
Не знают про понятия Симпл домейн модел от Рич домейн модели.
@user-yw9wx4lv2w
@user-yw9wx4lv2w 2 жыл бұрын
пугает фраза "в далеких 2000x"
@nikitalobanov8386
@nikitalobanov8386 2 жыл бұрын
Мужик в черном в конце правильно все подметил. Науменко явно не понимает суть DDD и интерпретирует многие вещи как ему хочется. Это уже не DDD.
@zond_amond
@zond_amond 2 жыл бұрын
DDD это не закон, это, внезапно, набор рекомендаций.
@raneddo
@raneddo Жыл бұрын
Если вы евангелист, не пытайтесь идеализировать понятия. DDD -- это подход, который описан для решения каких-то задач. Сказочники в книгах (к примеру тот же Роберт Мартин с чистым кодом) живут в идеальном мире, где доменный эксперт хочет общаться с вами по DDD, где цветочки цветут и розы пахнут. И очень забавно наблюдать, как идеалисты пытаются писать код по книжке. Но, как правильно подметил автор, DDD хорош тем, что его не нужно использовать полностью. Если команда говорит, что использует DDD в работе -- это значит, что они хотя бы 1% от подхода применяют у себя. И более того, если человек начинает применять полностью паттерны там, где не нужно или писать идеально чистый код во вред скорости разработки и работы с бизнесом -- скорее всего этот человек застрял с переходном возрасте
@vladimirmashkov
@vladimirmashkov 9 ай бұрын
48:28 - вот здесь те самые вопросы, которые раскрывают проблему представленного метода DDD. Дмитрию очень далеко до CTO, а он уже им стал. Бедная, бедная компания. Сколько же денег потеряет компания ... Но, это уже проблема найма 😊
@P7Vagrant
@P7Vagrant Жыл бұрын
Всё хорошо, но человеку который переключает камеры, руки бы оторвал.
@6537537
@6537537 2 жыл бұрын
Как-то все в кучу и много воды
@Wizardino1
@Wizardino1 5 жыл бұрын
не знаю, что хорошего в тотальном чтении того, что написано на слайдах безо всяких пояснений, примеров и интерпретаций....вышел прочитал свою же статью - ну ок, так прочитать любой может....ты тонкие места покажи, где могут возникать трудности, приведи примеры удачного и неудачного использования данной технологии ...и не по 100 слов в минуту, а с расстановкой и осознанием.....
@nikkik7261
@nikkik7261 10 ай бұрын
вть
@EshkinKot1980
@EshkinKot1980 4 жыл бұрын
Yii и DDD в принципе не сочетаются, такое впечатление что докладчик сам не понимает, что говорит.
@rugleb
@rugleb 3 жыл бұрын
Задающим вопросы лень встать? Что за неуважение к докладчику?
@driversti2
@driversti2 2 жыл бұрын
Вам важна суть вопроса и ответа, или уважение к докладчику решит проблемы вашего клиента? Что это за совдепский подход?
@rugleb
@rugleb 2 жыл бұрын
@@driversti2 Это элементарные нормы приличия...
@driversti2
@driversti2 2 жыл бұрын
@@rugleb это субъективно. Я не обижусь, если передо мной не встанут. И в моем окружении никто этого не требует, даже сразу говорят, что вставать не надо. Эти "элементарные нормы приличия" навязаны советским подходом, где к старшему (по возрасту, званию, должности и и.д.) нужно было их проявлять. Ценность в дискуссии и решении проблем клиента, а не в том кто перед кем встал. Я не навязываю свое мнение, это реакция на вашу реакцию. Только
@michealmltefive5510
@michealmltefive5510 4 жыл бұрын
ужасный рассказчик - зазубрил, своего понимания мало
@fayniy-hohol
@fayniy-hohol 10 ай бұрын
дядька вконце набомбил вопросами, унизил🤣
ONE MORE SUBSCRIBER FOR 6 MILLION!
00:38
Horror Skunx
Рет қаралды 10 МЛН
Отказоустойчивый Redis кластер. Александр Котыня
53:49
Многоликий DDD - Сергей Баранов
1:19:18
Конференция ArchDays
Рет қаралды 16 М.
What is DDD - Eric Evans - DDD Europe 2019
57:06
Domain-Driven Design Europe
Рет қаралды 252 М.
Dependency Rejection and TDD without Mocks. Антон Молдован
39:09
Съесть Собаку
Рет қаралды 8 М.
Сергей Баранов - Многоликий DDD
1:06:56