@Markusam

Какой метод реализации при подходе CQRS правильный?

Есть проект в котором пытаюсь внедрить подход CQRS(Command Query Responsibility Segregation) и есть в нем два модуля Order и Store. И например есть такой бизнес процесс как создание ордера. Что б его создать необходимо сперва у модуля Store проверить работает ли этот store, то есть проверить его рабочие часы и дневной лимит на продажу(модуль оперирует этими данными), если store работает мы создаем order. Я вижу тут два подхода к реализации:
  1. Реализовать это в application слое, например controller сначала делает запрос(query) в модуль Store на проверку работает ли этот store. Если успех то затем создаем соответствующую command из модуля Order и которая попадет в соответствующий handler который создаст order
  2. Реализовать все это в handlere который создает order. То есть с handlerа делается запрос в другой модуль, через api service, дальнейший алгоритм такой же как и в пункте выше. Просто принятие решения на создание и запрос в сторонний модуль переносится в handler который создает order.


Какой из способов предпочтительней и какой более правильный? Может есть другой способ?
  • Вопрос задан
  • 234 просмотра
Решения вопроса 1
vhood
@vhood
Не забывайте отмечать решения
Архитектура монолит.
например для Order это его классы которые лежать в папке Order, его Aggregate Root
У Вас модуль = агрегат? Это не одно и то же.

За пределами своего неймспейса модуля, классы напрямую не используются и не вызываются, кроме Api service классов
Модуль - самостоятельная единица, которая должна работать без других модулей. Low coupling, high cohesion. Представьте, что он может подключаться через composer, вот каким он должен быть? У Вас так?
Что за паттерн "Api service", который какие-то DTO отдает? У агрегата может быть id другого агрегата и этого ему должно быть достаточно.

У Вас один контекст? Когда кто-то говорит "Store" (или, скорее всего, склад), все имеют ввиду одно и то же? Store с точки зрения покупателя и Store с точки зрения какого-то другого актора (например, поставщика) - одно и то же?
Если нет, Вам стоит разделить 2 контекста и сделать 2 Store. Один самостоятельный, и один как поддомен у Order и тогда вся логика будет в Order.
spoiler
слой Application одного контекста не может ссылаться на слой Domain другого контекста

Если контекст единый, может Store не заслуживает быть самостоятельным агрегатом? Если все-таки заслуживает, Order может выполнять свои обязанности, имея только id из Store? Это "на подумать".

В любом случае, один агрегат может воспользоваться другим (но не получать напрямую его объекты для реализации своей логики, только использовать функционал Aggregate Root), но если ими можно воспользоваться в слое Apprication последовательно - это будет лучше.

сперва у модуля Store проверить работает ли этот store, то есть проверить его рабочие часы и дневной лимит на продажу
Мне кажется, очевидно, что если это все-таки 2 разных агрегата одного контекста, то Store даже бизнес-логику тут не реализует, нужно просто проверить спецификацию. Делать это нужно в Application, вызвать 2 агрегата последовательно. Не нужно делать это ответственностью Order.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы