cQrs, общие вопросы

Обсуждаем, как правильно строить приложения
Ответить
Bio man
Сообщения: 609
Зарегистрирован: 2013.07.22, 10:40

cQrs, общие вопросы

Сообщение Bio man » 2018.02.08, 14:44

Часто встречается реализация QueryBus для Query. Но нужна ли шина? Если нужна, то только для декораторов, но я не могу придумать таковых. Валидация, транзакционность для запросов не нужна, так зачем шина? Для логирования? Логгер можно в сам хендлер инжектить.
Если есть примеры декораторов, приведите, пожалуйста.

Буква Q к какому слою относится? Вроде-как это не домен, а параллельный (с доменом) слой для доступа к данным. БЛ в нем никакой нет, и сущностями мы в нем не оперируем. Так где мне расположить Q? Положить, рядом с доменом, ReadLayer (если есть более подходящее название, сообщите, пожалуйста)?

Сдается мне, общая схема будет примерно такой:
1. presentation создает Query (DTO), по аналогии с командой, и передает хендлеру. $result = $handler->handle($query)
2. Handler (сервисный слой?) обрабатывает Query, если нужно, трансформирует в "спецификацию" и делает запрос к ReadRepository.
P.S. "спецификация" не очень подходящий термин. Я имею в виду, трансформирует, например, в объект фильтра, по которому ReadRepository будет делать выборку. return $repository->getUsersByFilter($this->createFilter($query))
3. ReadRepository возвращает DTO определенного типа, например, UsersListQueryResult.

Правильно я понимаю общую схему?


Пока все, остальные вопросы будут вытекающими из ответов на эти.

anton_z
Сообщения: 354
Зарегистрирован: 2017.01.15, 15:01

Re: cQrs, общие вопросы

Сообщение anton_z » 2018.02.08, 14:56

Всегда думал, что cqrs это вообще не про слои, шины и dto а про разделение хранилищ. Пишем в одно - нормализованное, транзакционное и надёжное, читаем из друого - денормализованного и быстрого.
Последний раз редактировалось anton_z 2018.02.08, 15:17, всего редактировалось 4 раза.

Аватара пользователя
ElisDN
Сообщения: 5015
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: cQrs, общие вопросы

Сообщение ElisDN » 2018.02.08, 14:58

В простейшем случае Handler для Query - это и есть замена ReadRepository.

Bio man
Сообщения: 609
Зарегистрирован: 2013.07.22, 10:40

Re: cQrs, общие вопросы

Сообщение Bio man » 2018.02.08, 16:26

anton_z писал(а):
2018.02.08, 14:56
Всегда думал, что cqrs это вообще не про слои, шины и dto а про разделение хранилищ. Пишем в одно - нормализованное, транзакционное и надёжное, читаем из друого - денормализованного и быстрого.
Да, суть CQRS именно такова. Но нужно еще как-то это чтение реализовать.
ElisDN писал(а):
2018.02.08, 14:58
В простейшем случае Handler для Query - это и есть замена ReadRepository.
В простейшем, возможно. Но репозитории тоже нужны, по аналогии с репозиториями домена.

P.S. разумеется, CQRS я рассматриваю в рамках гексогональной архитектуры. Ну или DDD, разницы особой не вижу.

zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: cQrs, общие вопросы

Сообщение zelenin » 2018.02.09, 13:49

Bio man писал(а):
2018.02.08, 14:44
Часто встречается реализация QueryBus для Query. Но нужна ли шина?
для консистентности. В принципе и CommandBus не нужен.
Bio man писал(а):
2018.02.08, 14:44
Буква Q к какому слою относится?
Query/QueryHandler - это слой приложения = сервисный слой.
Bio man писал(а):
2018.02.08, 14:44
Вроде-как это не домен, а параллельный (с доменом) слой для доступа к данным. БЛ в нем никакой нет, и сущностями мы в нем не оперируем. Так где мне расположить Q? Положить, рядом с доменом, ReadLayer (если есть более подходящее название, сообщите, пожалуйста)?
Судя по этому ты думаешь, что C (Command/CommandHandler) как-то относится к домену, а Q якобы нет. И то и то - это слоя приложения. Какие реализации хэндлеров могут быть - это дело второе.
Bio man писал(а):
2018.02.08, 14:44
Сдается мне, общая схема будет примерно такой:
1. presentation создает Query (DTO), по аналогии с командой, и передает хендлеру. $result = $handler->handle($query)
2. Handler (сервисный слой?) обрабатывает Query, если нужно, трансформирует в "спецификацию" и делает запрос к ReadRepository.
P.S. "спецификация" не очень подходящий термин. Я имею в виду, трансформирует, например, в объект фильтра, по которому ReadRepository будет делать выборку. return $repository->getUsersByFilter($this->createFilter($query))
3. ReadRepository возвращает DTO определенного типа, например, UsersListQueryResult.

Правильно я понимаю общую схему?
ты общую схему слишком специфицировал, введя конкретные сущности. Общая схема будет такая:
Request -> Query ->QueryHandler -> Storage -> QueryResponse
Все остальное - детали реализации.

Bio man
Сообщения: 609
Зарегистрирован: 2013.07.22, 10:40

Re: cQrs, общие вопросы

Сообщение Bio man » 2018.02.09, 14:03

zelenin писал(а):
2018.02.09, 13:49
Bio man писал(а):
2018.02.08, 14:44
Часто встречается реализация QueryBus для Query. Но нужна ли шина?
для консистентности. В принципе и CommandBus не нужен.
Да, но с ним удобнее. А в случае с Query, QueryBus нафиг не нужен, ибо не во что декорировать.
zelenin писал(а):
2018.02.09, 13:49
Bio man писал(а):
2018.02.08, 14:44
Буква Q к какому слою относится?
Query/QueryHandler - это слой приложения = сервисный слой.
Да, согласен. Я имел в виду слой доступа к данным (репозитории для чтения, хотя склоняюсь больше к названию DataProvider).
zelenin писал(а):
2018.02.09, 13:49
Bio man писал(а):
2018.02.08, 14:44
Вроде-как это не домен, а параллельный (с доменом) слой для доступа к данным. БЛ в нем никакой нет, и сущностями мы в нем не оперируем. Так где мне расположить Q? Положить, рядом с доменом, ReadLayer (если есть более подходящее название, сообщите, пожалуйста)?
Судя по этому ты думаешь, что C (Command/CommandHandler) как-то относится к домену, а Q якобы нет. И то и то - это слоя приложения. Какие реализации хэндлеров могут быть - это дело второе.
Я подразумевал интерфейсы слоя DAL. По аналогии с репозиториями.

anton_z
Сообщения: 354
Зарегистрирован: 2017.01.15, 15:01

Re: cQrs, общие вопросы

Сообщение anton_z » 2018.02.10, 01:49

Bio man писал(а):
2018.02.08, 16:26
P.S. разумеется, CQRS я рассматриваю в рамках гексогональной архитектуры. Ну или DDD, разницы особой не вижу.
Разница есть и очень большая. DDD - это методология процесса анализа предметной области, проектирования и программирования ПО с целью получения реализации, максимально близкой (но не тождественной) к концептуальной бизнес-модели для облегчения понимания предметной области и коммуникации между заказчиками/потребителями и разработчиками. Гексагональная архтектура (или порты и адаптеры) - это конкретный тип логической архитектуры приложения. Гексагональная архитектура может быть применена в рамках DDD, а может и нет, можно использовать слоистую архитектуру, например. DDD более широкое понятие, чем архитектура, и оно состоит не из правил, а из рекомендаций.

Если так хочется изолироваться с помощью интерфейсов от конкретного хралища для чтения, я бы сделал так:

Код: Выделить всё


interface ProductReadRepository
{
  public function findOne($id);

  public function findAll() \Iterator;

  public function findOneByVendorId($id);

  //...

  public function createQuery(): Query;

}


interface Query 
{

  public function withName($name): Query;
  
  public function withSomething($something): Query;
  
  //...
  
  public function one();
  
  public function all(): \Iterator;

}


Эти интерфейсы можно использовать напрямую. Я думаю никакие шины, запросы, ответы тут ни к чему, они будут лишним балластом, бесполезными прослойками. Если такие репозитории начнут разрастаться (только если начнут, не надо сразу этого закладывать), можно разбить его на отдельные Query классы:

Код: Выделить всё

interface RelatedProductsQuery
{
  public function relatedTo($product_id): RelatedProductsQuery;

  public function one();

  public function all();

}

Писать шину запросов, только потому, что есть шина команд, по моему скромному мнению, совершенно неоправданно.

Простите за нескромный вопрос, а что за система у вас в разработке, что решили DDD использовать, если не секрет? Или вы только изучаете DDD?
Последний раз редактировалось anton_z 2018.02.12, 07:11, всего редактировалось 1 раз.

Bio man
Сообщения: 609
Зарегистрирован: 2013.07.22, 10:40

Re: cQrs, общие вопросы

Сообщение Bio man » 2018.02.10, 02:43

Спасибо за ответ. Идею в принципе понял.

Я знакомлюсь с DDD, но в работе использую только те идеи DDD, которые считаю уместными.
Например, идею репозиториев и сервисов (хотя, это больше из гексагональной темы).
Поэтому я добавил оговорку, что разницы для меня особой нет, в каком контексте рассматривать CQRS, ибо у меня не pure DDD, и pure DDD для текущего проекта не оправдано.

anton_z
Сообщения: 354
Зарегистрирован: 2017.01.15, 15:01

Re: cQrs, общие вопросы

Сообщение anton_z » 2018.02.10, 03:48

Bio man писал(а):
2018.02.10, 02:43
и pure DDD для текущего проекта не оправдано.
Это абсолютно нормально. Если верить Microsoft, полное следование рекомендациям DDD может быть полезно только в проектах, в которых имеются действительные трудности с пониманием предметной области и коммуникацией: https://en.wikipedia.org/wiki/Domain-dr ... advantages. DDD возник как решение конкретной проблемы - сложности с пониманием проекта и взаимодействием. Отсюда можно сделать вывод, что если таких трудностей не возникает - а они должны проявиться уже на начальных стадиях разработки проекта (так как сначала нужно понять предметную область), то нет смысла полностью абстрагировать доменную логику. При этом ничто не мешает взять из практики DDD только то, что реально приносит пользу. Для меня, например, таковой оказалась идея доменных событий.

Ответить