Павел
А вот как назвать и что рили называется юзкейсом из этого - вопрос интересный
Павел
Кто нить кикните уже ее с ее простынями неинтересными
Павел
@theantt внутри Domain/Order тоже есть юзкейс Create, а Бизнес процесс - это несколько юзкейсов
Павел
да бы не создавать претендентов для других
Павел
Не мой скрин, но идея такая как-то
Павел
Ты же получается создаешь наружний юзкейс и там жонглируешь разными сущностями из разных контекстов? И смысл тогда от контекста. Тот же "ком грязи"
The Ant
чтоб не шарица по модулю и не искать куда разложена бл ) всё в одном месте и сразу понятно где )
The Ant
Хотя с доменом на скрине вполне понятно
The Ant
но, я чот сомневаюсь что кто-то прям упарывается по правильному ддд :D
The Ant
@theantt внутри Domain/Order тоже есть юзкейс Create, а Бизнес процесс - это несколько юзкейсов
ну и бизнес процесс хз конешь, обычно при создании ордера задействуется куча всего )
Павел
ну и бизнес процесс хз конешь, обычно при создании ордера задействуется куча всего )
Ну вот куча всегдо как раз должно быть в процессе, но при этом самой логики там нет, как раз выхов других контекстов
The Ant
почему нельзя положить в домене действия какие-то?
Павел
Не понял вопроса
Павел
Есть БЛ а есть координация
The Ant
типа Domain/Order/BL/CreateOrder
Павел
типа Domain/Order/BL/CreateOrder
Прикол в том, что CreateOrder -это не домен даже)
Павел
Это апликуха
The Ant
Да, но действия какие-то внутре
The Ant
т.е. как помне удобно держать всё что касается домена внутри домена, не?
The Ant
или обязательно надо разделить по нескольким местам код?
Павел
т.е. как помне удобно держать всё что касается домена внутри домена, не?
Что такое домен, что ты хочешь держать все внутри него? Вот есть создание заказа. Например надо создать заказ в контексте производств заказа, потом денюжки списать в контекте финансов -это все "создание заказа". В каком одном домене это должно находитьс по твоему?
The Ant
вопрос вопрос 😄 я не знаю
Gleb
Потому что по тому же ДДД это не одно и тоже. Соответственно не будет единого языка
Павел
Так это кажется разные предметные области. По мне это не должно лежать вместе (но я не знаю, я баклажан)))
Ну вот это вопрос к Муравью, ведь это "создание заказа" и должно произойти и быть описано в одном месте, может даже в одной транзакции (хотя кто-то меня ударит палкой за это)
Gleb
Скорее тогда отдельные сущности по предметным областям и какой-то агрегейт с транзакцией
Павел
Скорее тогда отдельные сущности по предметным областям и какой-то агрегейт с транзакцией
Ну я сам грамотно не могу ответить (да и не знаю), но да как то так. Это как раз по скрину выше
Gleb
Так скрин выше эту ситцауию не описывает совсем. там просто заказ. Это может быть как уже агрегацией, так и заказом, судя по всему, финансовым, если переложить на последний пример.
The Ant
если подумать, то должна быть какая то штука снаружи ``` // begin transaction if ($balance < $orderCost) { // rollback return; } $orderDomain->createOrder(123) $balance--; //commit
The Ant
а как?
Юра
Все эти balance++, balance--
The Ant
да это условный код )
The Ant
понятно что там сервисы будут какие-то, которые отвечают за списание средств
The Ant
и всё это должно быть в рамках одной транзакции
Юра
Все это должно быть либо атомарно, либо с блокировкой на чтение
Юра
Иначе будет неправильное списание
Павел
Так скрин выше эту ситцауию не описывает совсем. там просто заказ. Это может быть как уже агрегацией, так и заказом, судя по всему, финансовым, если переложить на последний пример.
В скрине выше, что есть Домен Order (там правда нет отдельных экшенов), а есть еще процесс Создать заказ, который более глобальный
Павел
CreateOffer/{Command, Handler}
Да так и делаем, только /UseCase/Create/{Command, Handler} . Вообще вопроса никакого не было, это Муравей предложениями засыпал)
Павел
Все это должно быть либо атомарно, либо с блокировкой на чтение
Это можно сделать оптимистичнй блокировкой
Павел
А если поток данных большой, то скорее всего уже асинхронно с откатами
Павел
The Ant
$orderId должен откуда-то браться? )
Павел
$orderId должен откуда-то браться? )
Uuid,можно вернуть из одного из хандлеров, или какой то генератор идентфиикаторов
The Ant
все таки я думаю правильно. операции создания ордера и собственно покупка(оплата) несколько разные штуки
Павел
$orderId = $manufactureHandler->createOrder($orderParams) $id = $financeHandler->buyOrder($cost,$orderId ),
The Ant
конечно надо исходить из реальных задач, возможно предоплата понадобится для создания заказа. Но и это будут разные операции
Павел
все таки я думаю правильно. операции создания ордера и собственно покупка(оплата) несколько разные штуки
да, разные, поэтому разные контексты, которые соединяютс по средствам процессов синхронных или саг
Павел
Крутые дяди сказали бы что только асинхронно, только саги, только один агрегат в одной транзакции
Павел
Но мы пока не доросли, можно и гавнять, чтобы не обосраться
Павел
А потом уже фиксить и быть крутым по месту
The Ant
да, разные, поэтому разные контексты, которые соединяютс по средствам процессов синхронных или саг
ну в мессенжере можно что-то подобное сделать, через конверт со штампом "если успешно". не помню как он называется ) Имею в виду передать в следующую команду.
The Ant
получится цепочка команд
The Ant
ну да, такое себе
The Ant
в модульном монолите я думаю не зазорно дернуть сервис из другого модуля 😄
The Ant
хотя идеологически это хуевое действие :D
Павел
А просто монолит
The Ant
Тогда это уже не модульный монолит)
если дергать публичные методы модуля (а его рассматривать как домен)... 🤣🤣
Павел
То что есть публичное апи, в данном случае это юзкейсы(ну или еще что то), и только их дергать снаружи
Павел
Тут просто еще вопрос правильного размера контекста
Павел
Просто если контекст будет не очень, то и получится, что надо постоянно дергать данные друг у друга, как то их шарить и прочее. Возможно это один контекст
Павел
Короче вопрос не простой, ну по крайней мере для меня
The Ant
согласен, чот как-то сложновато
Павел
У меня например основные сложности, что делать если сделать асинхронное создание заказа и списание денег. А если денег нет, значит надо какую то конпенсацию, отмену заказа, а если упадет очередь или какая то ошибка, как это обнаружить. Значит надо сагу (епт что это такоеXD XD XD ) , какие то проверку по крону наверное. Проще в транзакцию и синхронно)) так и гавняю
The Ant
Ну, исходить из задач конечно. Зачем создавать заказ асинхронно, если это операция вставки данных в таблицу? непонятно )
Павел
Ну, исходить из задач конечно. Зачем создавать заказ асинхронно, если это операция вставки данных в таблицу? непонятно )
Потому что 1 агрегат - одна транзакция, это как раз к вопросу о блокировках и их умньшению. Ну и плюс какие до дейсвтия могут занимать больше времени чем хотелось бы для синхронной обработки
The Ant
ну и не правильно наверное привязывать какое-то действие к одному агрегату, особенно если это действие затрагивает несколько агрегатов
Юра
Блин там с одноуровневыми проблем хватает, а вы ещё многоуровневые хотите )
Юра
Это можно сделать оптимистичнй блокировкой
На большой нагрузке ты быстро поймёшь что это вообще не вариант
Павел
транзакции могут быть многоуровневыми. если у тебя 1 бд )
Это понятно, но это не гуд, так как большая внешняя тразакция - основная, и за это время могут еще что то делать и шанс фейла блокировок больше
The Ant
к примеру юзер на сайте сформировал корзину, там 3 товара. Два из них есть на локальном складе, а 1 по запросу доставляется. тут уже надо спрашивать у бизнеса, че делать если корзина не оплачена? лочить эти 2 товара на локальном складе или нет? надо ли делать запрос на доставку третьего в магаз? Или всё это делать тока после оплаты заказа? В итоге у нас или просто будет запись в бд, или с походом в сторонний сервис, чтобы сделать там заявку