2014-11-11 3 views
8

В настоящее время я начинаю свою первую реальную попытку системы DDD/CQRS/ES после изучения большого количества материала и примеров.Должны ли агрегаторы быть обработчиками событий

1) Я видел примеры сорсинга событий, где заполнители обработчиков событий и их метод Handle для каждого события, что мутирует состояние на экземпляре объекта (они реализовать < типСобытия > интерфейса IHandleEvent для событий, которые мутируют состояние)

2) Я также видел примеры, когда Агрегаты будут просто выглядеть как обычные классические классы Entity, моделирующие домен. Другой класс обработчика событий связан с изменением состояния.

Состояние, конечно же, при сборе агрегата от вызова репозитория, которое получает все предыдущие события для этого агрегата, конечно, мутируется в агрегате обработчиками событий, и когда обработчик команд вызывает методы в совокупности. Хотя в последнем я видел примеры, когда события публикуются в обработчике команд, а не в совокупности, что, я уверен, неверно.

Мой вопрос, каковы плюсы и минусы между методом (1) и (2)

+0

Интересно, как выглядит поток выполнения в подходе 2). Как изменяется состояние отдельного обработчика событий в агрегате?Вам нужно разоблачить все государство? Это делается с помощью метода на агрегате? Каким должно быть имя такого метода, по сравнению с именем метода, вызываемым обработчиком команд и создающим событие? Разве это не надуманно? – guillaume31

+0

В ходе дальнейшего рассмотрения кода примера для 2 и того, что, как я думал, он делает, я пришел к выводу, что это очень странный подход и, как вы говорите, надуманный и чрезмерно спроектированный. Я чувствую, что должен отредактировать вопрос, чтобы просто спросить, является ли подход (1) общим подходом к шаблону источника событий с агрегатами, или есть другой способ, которым я не подвергался? (однако не нужно обсуждать моментальные снимки, поскольку я чувствую, что я понимаю его место, когда это необходимо) –

+0

Я только видел метод 1) до сих пор с функциональными вариантами, где часть поведения обработчика команд переходит в сам агрегат. – guillaume31

ответ

8

Работа приема/обработки команды отличается от воздействующий его. Подход, который я принимаю, - это иметь обработчик. Это задача получить команду. Команда удерживает AggregateId, который затем может использовать для получения всех событий для совокупности. Затем он может применять эти события к совокупности с помощью метода LoadFromHistory. Это позволяет обновить агрегат и сделать его готовым к приему команды. Итак, моя короткая версия - это вариант 2.

У меня есть сообщения, которые вы считаете полезными, первый - это обзор потока типичного приложения CQRS/ES. Это не так, как должно быть так, как они часто бывают. Вы можете найти это на CQRS – A Step-by-Step Guide to the Flow of a typical Application!

У меня также есть сообщение о том, как создать общий корень для CQRS и ES, если это полезно. Вы можете найти это на Aggregate Root – How to Build One for CQRS and Event Sourcing

В любом случае, я надеюсь, что это поможет. Все самое лучшее здание вашего приложения CQRS/ES!

+1

Выбрал это как ответ, так как информация и пример в вашем блоге были очень полными и понятными. Я также согласен с тем, что пример Грега Янга является лучшим для тех, кто пытается изучить источники событий и cqrs. Единственный комментарий и изменение, которые я лично хотел бы предложить, - не передавать фактический объект команды в агрегированный объект, а вместо этого извлекать данные из команды в обработчике и передавать его в метод, представляющий поведение домена. В этом смысле я согласен с MikeSW в том, что это в основном деталь реализации. Также Codescribler, весь ваш блог блестящий! –

+1

... но вариант 2 из вопроса касается отдельного * Обработчика событий * для изменения состояния, а не * Command Handler * для обработки входящих команд, правильно? @Codescribler, я не вижу, как ваш (разумный) рекомендуемый подход относится к варианту 2. – guillaume31

+0

Фактически guillaume находится прямо там, что я бы сказал, что описано в ответе, это вариант 1 без наличия интерфейсов IHandle в совокупности (поэтому агрегат не является зарегистрированным обработчиком событий, события просто применяются для изменения состояния). То, что я описал в варианте 2, я чувствую, что-то очень неправильно. Возможно, это помогло бы ясности удалить ссылку на вариант 2 в ответе. –

2

Пока я согласен с Codescribler, мне нужно углубиться в детали. ES составляет около , выражая состояние объекта как поток событий (который будет сохранен). Обработчик сообщений - это просто реализация службы, которая сообщает Entity, что делать.

С ES объект реализует свои изменения, генерируя одно или несколько событий, а затем применяя их к себе. Сущность не знает, что ее изменения исходят от обработчика команд или событий (он должен быть «всегда» обработчиком команд, но хорошо .. иногда это не имеет значения), однако он изменяет состояние через свои собственные события, которые будут опубликованы службой (или самим хранилищем событий).

Но ... в недавнем приложении по прагматическим причинам мой ES-объект принял команды напрямую, хотя сам объект не был реализацией обработчика команд. Обработчик просто передаст команду объекту.

Таким образом, вы можете обрабатывать сообщения непосредственно с сущностью, но только как деталь реализации, я бы не рекомендовал назначать сущность как обработчик команд/событий, поскольку это является нарушением Разделения проблем.

+0

Если объект не является обработчиком команд, как генерируются события сущности/агрегата? В ответ на что? –

+0

Я реализую службы приложений как обработчики команд, агрегирует генерирует события в ответ на метод, вызванный службой приложения. – MikeSW

+0

Почему эта делегация? Что еще нужно, чтобы служба приложения, которую нужно выполнить до этого, вызывает метод на агрегате? –

Смежные вопросы