Тёмный

Денис Цветцих - Rich Model и Anemic Model: враги или друзья 

DotNext — конференция для .NET‑разработчиков
Просмотров 2,7 тыс.
50% 1

Опубликовано:

 

14 окт 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 22   
@БогданГуківський
По DDD есть ряд замечаний. Делать персональные ВО для всех полей для избежания ошибочного присвоения - очевидная глупость, не знаю кто и где так советует делать. Такое имеет смысл только для ID, типов которых будет не много, а шанс на ошибку и ее критичность большие. VO прекрасное место для размещения методов валидации, которые могут быть вызваны в application слое при построении этих самых VO(например, в VO могут быть фабричные методы, порождающие этот VO на основе более примитивного типа или возвращающие ошибку валидации). О том, что инфраструктура хранения плохо работает с ВО - если говорить о ORM типа EF, да, ИНОГДА бывает сложновато, но всегда решаемо. Да и хранилище не всегда relational database за EF, это может быть relational database без EF, с EF и отдельной persitence моделью, document DB, kev-value db или вовсе event store, где такой проблемы может и не быть или она уже и так решается иным образом. По агрегатам - задача агрегата определить границы строгой консистентности. Что с агрегатом, что без - исполнения этого бизнес требования по строгой консистентности несет неизбежные расходы по производительности. С примера по заказу: если смена одного orderItem не требует обновления всего заказа или позволяет это сделать с eventual consistency - то границы агрегата с примера выбраны неверно. Если не позволяет - то подход с обновлением одного orderItem принесет когда-то кому-то баг и создаст уязвимость вроде покупки 1М товаров по стоимости одной штучки)). Вероятно, понимание автором концепции агрегата искажено, если возникает постоянное желание как-то их частично редактировать, или редактировать несколько в одной транзакции. События - это часть агрегата (тот же подход event sourcing, сохраняет только эту часть, так как состояние можно восстановить), по этому их сохранения в одной транзакции с состоянием не нарушает это правило, а наоборот его подтверждает. Вся пляска с Outbox - проблема инфраструктуры, а не домена, вызванная желанием хранить состояние и события в разных хранилищах, между которыми нет стандартного механизма распределенных транзакция. Пример с патчем крайне странная вещь. Если в домене есть понятия установки свойств моделируемой сущности, то ничто не мешает сделать их сеттеры публичными. DDD не запрещает публичные сеттеры, просто не так уж и часто в домене есть операция - установить свойство. Обычно домен имеет более специальные операции, следствием которых есть изменения значения свойств модели. Так же модель может и метод ApplyPath поддерживать, и это никак не нарушит инкапсуляцию, если и правда в данной предметной области есть такое действие. Это не запреты в DDD, это маркеры для обращения внимания, ибо ЧАСТО наличие такого говорит о слабом понимании предметной области и больших серых зонах, которые закрываются в такой способ и за что будет позже расплата. Ну или о слишком простой модели, где DDD просто не нужно, как и разработка отдельного программного продукта, и где задачу проще решить универсальной noCode платформой. Главный мой совет - не стоит заниматься Карго DDD, продолжая мыслить на Transaction Script манер. Если TS позволяет решать ваши задачи хорошо - вам не нужен DDD. DDD- это инструмент борьбы с доменной сложностью, для применения которого должна быть эта самая сложность и умение его применять у ВСЕЙ команды проекта. Применять разные практики с DDD частично - также возможно, главное делать с умом. Никто не запрещает применять стратегические паттерны вроде единого языка, ограниченных контекстов и способов их интеграции и при этом внутри контекста не применять тактические паттерны и использовать TS подход. И наоборот, никто не мешает в монолитном приложении использовать агрегаты и ВО. Главное понимать суть этих шаблонов и применять их там, где они уместны.
@VoroninPavel
@VoroninPavel Год назад
Пример с жирным аггрегатом в виде заказа как бы намекает на то, что аггрегат, возможно, выбран не самым правильным образом. У аггрегата лишь одна задача - обеспечение транзакционной целостности множества сущностей. Если можно изолированно менять строку заказа, то аггрегат - это именно она. А дальше уже начинаются пляски, если существуют бизнес-правила для всего заказа целиком. Тут придется выбирать, или все-таки считать аггрегатом весь заказ и решать проблемы производительности иными способами, или городить огород с сагами, синхронной обработкой событий, откатом изменений (а это сложно, дорого, и вся операция все равно будет длинной во времени). По мне уж лучше медленный, но корректный код, чем быстрый, но с шансом, что он какие-то бизнес инварианты пропускает. P.S. Спасибо за до клад. Есть над чем подумать. ;-)
@MaxRozov
@MaxRozov Год назад
Ну как-то... не знаю. Постоянно возникает ощущение, что любую из двух моделей (anemic vs rich) критикуют люди, плохо в ней разобравшиеся. Ибо обе - прекрасно работают в прямых руках. Например - критика value objects на основе тезиса о "невозможности фильтрации по полям" вроде как упускает реальные возможности EF, в частности - OwnsOne, всё там можно. Критика агрегатов на основе тезиса "в заказе слишком много позиций" как бы сходу ставит под сомнение И логику выделения такого "жирного" Агрегата вообще И понимание докладчиком самой сути этого паттерна, а суть в том, что если "просто изменить одну позицию заказа", то у вас может "просто отъехать вычисление скидки, кешбека и т.п.". Если Order и его OrderItem-ы не атомарны, так и нефиг их объединять в один Агрегат. В целом, современная разработка в рамках DDD на тактическом уровне - это постоянное балансирование между атомарностью Агрегата и распределённостью логики посредством Domain Events (с синхронизацией изменений различных агрегатов посредством транзакций).
@DzhigurdaAnton
@DzhigurdaAnton Год назад
Прошу Автора посмотреть доклад Владимира Хорикова про Валидацию в ДДД про объекты значения, там вопрос на 27 минуте в этом видео полностью и детально рассмотрен. Я думаю автор получит удовольствие от просмотра и ответы на вопросы заявляенные в этом видео.
@smilesrg
@smilesrg 11 месяцев назад
Спасибо, провели хороший ресёрч, очень ценный доклад!
@horsehorse9399
@horsehorse9399 Год назад
Я как-то упустил момент во времени: когда это публичный сеттер стал нарушением инкапсуляции? Свойства для инкапсуляции изначально и задуманы (это же просто 2 метода, ну и + поле под ними, если это автопроперти). Звучит как какой-то нонсенс. Если нужно задать значение извне, то он обязан был публичным, не нужно для него городить отдельный метод (он сам собой именно им и является).
@БогданГуківський
Если задание любого значения свойству не нарушает инварианты сущности - оно спокойно может обладать паблик сеттером и модель при этом не прекратит быть рич.
@nikitagrishin5891
@nikitagrishin5891 Год назад
Позиция и изыскания автора объясняются тем что он сразу загнал себя в угол одной универсальной моделью без разделения на business entity и data entity и попытался на нее натянуть все консёрны одним махом
@DzhigurdaAnton
@DzhigurdaAnton Год назад
Про размер агрегата можно почитать Вон Вернона красную книгу, там обсуждаются размеры. Проблема в том, что они считают что агрегат это граница транзакционной согласованности в первую очередь, и чем больше агрегат, тем внутри него должны быть более изощрённые правила согласования кластера объектов, которыми и обоснован размер. Как правило один Агрегат соответствует одной сущности. Плюс в большинстве систем эти агрегаты собираются из событий предметной области и лежат в памяти как целый агрегат. Пол книги автор рассказывает про распределённоые системы. Идея в том, что у вас может быть много серверов с частью агрегатов, а не один сервер и база на петобайты.
@bananasba
@bananasba Год назад
Нельзя сидеть на двух стульях, а именно пытаться сделать вид, что на сущностях из базы данных можно реализовать ддд.
@БогданГуківський
Если и возможно - то только при таком низком уровне сложности модели, где и без ДДД можно, а скорее, и вовсе без написания кода решить эту задачу в раз 10 дешевле используя (no/low)Code сервис.
@DimonSmart
@DimonSmart Год назад
Мне нравится тема разделения модели и поведения. И предложенный способ валидации на уровне проекта (чтобы в сеттеры модели лазить только из одного проекта) выглядит очень красиво. А вариант когда модель нашпиговывают всеми имеющими отношение к модели методами выглядит не как Rich а скорее как Big Ball of mud. Особенно это заметно присложных многострочных методах
@NoldoWalker
@NoldoWalker Год назад
Очень комплексно рассказано, спасибо!
@native-nature-video
@native-nature-video Год назад
Спасибо за видео!!!
@VoroninPavel
@VoroninPavel Год назад
Проблема в том, что инкапсуляция - контекстное понятие, но языки программирования такую штуку практически никак не поддерживают. Тот же ORM болт кладет на инкапсуляцию и лезет в private члены entity или использует private конструктор.
@VoroninPavel
@VoroninPavel Год назад
JsonPatch - это про REST, но DDD больше про команды, а не про ресурсы. Если клиенту приехала DTO-портянка заказа со всеми строками (read model), это не значит, что обязан существовать endpoint, который точно такую же DTO ест.
@alexanderzakharov-u1b
@alexanderzakharov-u1b Год назад
Мне одному кажется, что все проблемы Rich-модели были бы решены, если в c# добавить понятие дружественных классов, которое есть в с++?
@maxarshinov
@maxarshinov 4 месяца назад
Они уже есть. Nested классы имеют доступ к private родителя.
@АлександрКубит-з2е
@АлександрКубит-з2е 3 месяца назад
Вероятно вы ищите способ как поделиться внутренней реализацией, с определённым классом, это довольно просто можно сделать с помощью делегатов
@AlexanderRadchenko
@AlexanderRadchenko Год назад
По имени!
@bananasba
@bananasba Год назад
Вода, кругом вода, больше водыыы
Далее
Is an Anemic Domain Model an Anti-Pattern?
9:54
Просмотров 22 тыс.
РЫБКА С ПИВОМ
00:39
Просмотров 387 тыс.
Николай Пьяников - Чистый DI
58:50
How To Use Domain-Driven Design In Clean Architecture
30:27
КАК УСТРОЕН TCP/IP?
31:32
Просмотров 171 тыс.
Проблемы обучения от 0+
42:42
РЫБКА С ПИВОМ
00:39
Просмотров 387 тыс.