cQrs, общие вопросы
cQrs, общие вопросы
Часто встречается реализация 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.
Правильно я понимаю общую схему?
Пока все, остальные вопросы будут вытекающими из ответов на эти.
Если есть примеры декораторов, приведите, пожалуйста.
Буква 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.
Правильно я понимаю общую схему?
Пока все, остальные вопросы будут вытекающими из ответов на эти.
Re: cQrs, общие вопросы
Всегда думал, что cqrs это вообще не про слои, шины и dto а про разделение хранилищ. Пишем в одно - нормализованное, транзакционное и надёжное, читаем из друого - денормализованного и быстрого.
Последний раз редактировалось anton_z 2018.02.08, 15:17, всего редактировалось 4 раза.
Re: cQrs, общие вопросы
В простейшем случае Handler для Query - это и есть замена ReadRepository.
Re: cQrs, общие вопросы
Да, суть CQRS именно такова. Но нужно еще как-то это чтение реализовать.
В простейшем, возможно. Но репозитории тоже нужны, по аналогии с репозиториями домена.
P.S. разумеется, CQRS я рассматриваю в рамках гексогональной архитектуры. Ну или DDD, разницы особой не вижу.
Re: cQrs, общие вопросы
для консистентности. В принципе и CommandBus не нужен.
Query/QueryHandler - это слой приложения = сервисный слой.
Судя по этому ты думаешь, что 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
Все остальное - детали реализации.
Re: cQrs, общие вопросы
Да, но с ним удобнее. А в случае с Query, QueryBus нафиг не нужен, ибо не во что декорировать.
Да, согласен. Я имел в виду слой доступа к данным (репозитории для чтения, хотя склоняюсь больше к названию DataProvider).
Я подразумевал интерфейсы слоя DAL. По аналогии с репозиториями.
Re: cQrs, общие вопросы
Разница есть и очень большая. 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;
}
Код: Выделить всё
interface RelatedProductsQuery
{
public function relatedTo($product_id): RelatedProductsQuery;
public function one();
public function all();
}
Простите за нескромный вопрос, а что за система у вас в разработке, что решили DDD использовать, если не секрет? Или вы только изучаете DDD?
Последний раз редактировалось anton_z 2018.02.12, 07:11, всего редактировалось 1 раз.
Re: cQrs, общие вопросы
Спасибо за ответ. Идею в принципе понял.
Я знакомлюсь с DDD, но в работе использую только те идеи DDD, которые считаю уместными.
Например, идею репозиториев и сервисов (хотя, это больше из гексагональной темы).
Поэтому я добавил оговорку, что разницы для меня особой нет, в каком контексте рассматривать CQRS, ибо у меня не pure DDD, и pure DDD для текущего проекта не оправдано.
Я знакомлюсь с DDD, но в работе использую только те идеи DDD, которые считаю уместными.
Например, идею репозиториев и сервисов (хотя, это больше из гексагональной темы).
Поэтому я добавил оговорку, что разницы для меня особой нет, в каком контексте рассматривать CQRS, ибо у меня не pure DDD, и pure DDD для текущего проекта не оправдано.
Re: cQrs, общие вопросы
Это абсолютно нормально. Если верить Microsoft, полное следование рекомендациям DDD может быть полезно только в проектах, в которых имеются действительные трудности с пониманием предметной области и коммуникацией: https://en.wikipedia.org/wiki/Domain-dr ... advantages. DDD возник как решение конкретной проблемы - сложности с пониманием проекта и взаимодействием. Отсюда можно сделать вывод, что если таких трудностей не возникает - а они должны проявиться уже на начальных стадиях разработки проекта (так как сначала нужно понять предметную область), то нет смысла полностью абстрагировать доменную логику. При этом ничто не мешает взять из практики DDD только то, что реально приносит пользу. Для меня, например, таковой оказалась идея доменных событий.