Воспроизведение событий - проверка переходов
Мне интересно, какая именно логика должна содержаться при применении события к состоянию при воспроизведении событий с использованием какого-либо решения для поиска событий.
В частности, меня интересует проверка, скажем, у меня есть объект, который может находиться в одном из следующих состояний:
- Записан
- активный
- близко
- отменен
и прогресс должен быть Записан-> Актив-> Закрыть или Записан-> Актив-> Отменен, мы не можем перейти от Записано к Закрытию непосредственно, например.
Теперь, я понимаю, проверка должна содержаться в командах: UpdateState
проверит, позволяет ли текущее состояние объекта перейти к желаемому, и выдаст соответствующее событие StatusUpdated
который будет сохранен в хранилище событий.
Вопрос в том, что мне делать при воспроизведении? Должен ли я просто обновить статус или выполнить ту же проверку (чтобы при изменении требований к изменению статуса не было возможности загрузить некоторые ранее обновленные объекты, если мы не добавим дополнительную логику), чтобы гарантировать, что мы не закончим с сущности, которые не удовлетворяют нашей нынешней логике?
PS. Я думаю, что у меня есть проблемы с пониманием этого, потому что в моем понимании события необходимы просто для "объявления" того, что уже произошло (и состояние отправителя уже изменено), чтобы заинтересованные стороны могли реагировать соответствующим образом. И в случае загрузки / воспроизведения событий, вам нужно изменить указанное состояние, вместо того, чтобы что-то "объявлять"...
2 ответа
Вам не нужно выполнять какую-либо проверку при воспроизведении потока событий.
Команды моделируют то, что будет сделано в будущем: вы просите систему сделать что-то для вас. Система должна решать, делать это или нет, например, на основе бизнес-правил и проверки.
События в отличие от моделируют вещи, которые уже произошли. Как и в реальности, вы не можете изменить прошлое.
Таким образом, это означает, что, когда событие сохраняется, это было следствием команды, которая была принята как действительная в тот момент, когда оно было обработано. Воспроизведение потока событий просто означает посмотреть на то, что произошло в прошлом, и вы не можете это изменить.
Следовательно, вам не нужно снова запускать проверку.
Более того, это означает, что если однажды ваша бизнес-логика изменится, все вещи (деловые аварии!), Которые произошли в прошлом, все еще произошли, поэтому они не должны меняться. Следовательно, вам не разрешается использовать какую-либо логику проверки, так как сегодня она может быть другой, чем когда вы хранили события.
И снова: Вы не можете (и не должны) менять прошлое:-)
пример
Предположим, у вас есть способ проверки номеров кредитных карт. Клиент приходит в ваш магазин, платит, вы считаете его / ее карту действительной, учитывая ваш текущий набор правил, и все в порядке.
Затем однажды институт кредитных карт меняет способ расчета номеров кредитных карт, и, следовательно, у вас есть другой алгоритм проверки.
Когда вы сейчас воспроизводите свои прошлые события, платеж произошел с новыми правилами проверки или без них, и вы не можете изменить тот факт, что это произошло! Если вы хотели, вам нужно было создать новую транзакцию, чтобы отправить деньги обратно клиенту. Опять же, это приведет к новому событию, а не к измененному прошлому.
Итак, вкратце: не сверяйте события ни с чем. Они действительны по определению, как и раньше.
Любой поток событий, записанный в хранилище событий, должен быть допустимым для воспроизведения без введения какой-либо логики в обработчики событий. Если вам нужно изменить процесс перехода, вам нужно взглянуть на какое-то преобразование в соответствии с примерами.
Что касается вашего последнего пункта. Источник событий - это метод сохранения и восстановления состояния объекта с использованием хронологической записи упорядоченных событий. Так получилось, что когда вы сохраняете сущность, вы также можете опубликовать эти события для любых заинтересованных сторон.