Можно ли создавать огромные события в Event Sourcing?

Мы используем источник событий и создаем агрегаты из потока событий. У меня 2 агрегата - А1 и А2. A1 используется в качестве шаблона для создания A2. Размер А1 может быть довольно большим. Основная идея Event Sourcing заключается в том, чтобы гарантировать, что каждое изменение в состоянии приложения фиксируется в объекте события. Таким образом, чтобы сохранить A2, мы должны хранить много информации в первом событии.

Это обычная ситуация или создание из шаблона не очень хорошая идея? Есть ли лучший способ решить это?

2 ответа

Решение

Это помогло бы больше, если бы вы опубликовали более конкретные примеры ваших агрегатов и событий. В общем, вы можете создавать более детальные события, если это имеет смысл в вашей ситуации. Тогда вместо отношения 1-1 между Командой и Событием у вас будет отношение 1-N, которое полностью соответствует теории CQRS.

Итак, чтобы дать вам пример:

CreateInvoice : Command
- InvoiceId
- Customer (10 fields)
- Address (5 more fields)
- InvoceLine[] (where each InvoiceLine also have 10 fields or so)
- Rest of 100 or so fields

InvoiceCreated : Event
- InvoiceId
- Customer (10 fields)
- Address (5 more fields)
- InvoceLine[] (where each InvoiceLine also have 10 fields or so)
- Total
- Rest of 100 or so fields

И в командном обработчике:

void Handle(CreateInvoce cmd)
{
  var invoice = new Invoice(cmd.InvoiceId, cmd.Customer, cmd.Address, cmd.Lines ....)
  uow.Register(invoice);
}

где будет создано только одно событие InvoceCreated.

Вместо этого вы можете иметь более детализированные события:

InvoiceCreated : Event
- InvoiceId
- Customer
- Address

InvoiceLineAdded
- InvoiceId
- Item
- Vat
- Subtotal
- Etc

Затем в командном обработчике:

void Handle(CreateInvoce cmd)
{
  var invoice = new Invoice(cmd.InvoiceId, cmd.Customer, cmd.Address);

  foreach (var line in cmd.Lines)
  {
      invoice.AddLine(line.Item, line.Quantity, line.Price, ...);
  }

  uow.Register(invoice);
}

Здесь ctor будет вызывать событие InvoiceCreated, а метод AddLine будет вызывать событие InvoiceLineAdded. Затем вы можете иметь такие события, как InvoiceLineChanged/InvoiceLineRemoved, которые вы можете использовать с обновлениями.

Это позволит вам иметь более детализированные события, в то же время позволяя выполнять более грубые команды.

Большие команды в порядке, когда они представляют атомарные действия от пользователя / системы PoV.

PS Об использовании агрегата в качестве шаблонов я бы не стал беспокоиться, а вместо этого создам структуру данных, которая будет служить аккумулятором для сбора промежуточного состояния. Затем он может быть просто сериализован / десериализован. Если за заполнением шаблона нет поведения - вам не нужны агрегаты. Это просто блок данных, который впоследствии будет использоваться для создания совокупности и запуска бизнес-правил. Вы, вероятно, используете этот "шаблонный" объект для хранения введенного пользователем состояния между несколькими запросами, например, состояния сеанса, верно;)?

Надеюсь, это поможет.

У меня был похожий вопрос: насколько гранулированным должно быть доменное событие?

Обычно огромный класс означает, что вы должны проверить его обязанности и разделить его на более мелкие классы в соответствии с SRP. По агрегатам, событиям домена и т. Д. Вы можете следовать тому же подходу. При слишком большом количестве классов вы можете думать о нескольких ограниченных контекстах и ​​так далее...

Другая часть проблемы в том, что команда и гранулярность события - это бизнес-решение. Если ваше огромное событие имеет смысл в вашей доменной модели, используйте его. В противном случае вы (или эксперт по доменам) должны спросить себя, каковы намерения пользователя и выражает ли это текущее событие? Просто очень простой пример, вы можете иметь даже очень маленькие доменные события: PhoneNumberChanged или даже меньше: PhoneNumberCorrected, PhoneNumberMigrated (все они содержат только одно свойство, новый номер телефона). В соответствии с этим, вы можете иметь огромные события. Ofc. поддерживать их намного сложнее, через некоторое время вы, вероятно, начнете создавать версии или перенести все хранилище событий в другую структуру домена.

Трудно помочь больше, не зная ничего о проблеме. Вероятно, вы должны рассказать нам кое-что о том, что произошло за последние годы с вашим огромным событием в области доменов.

Другие вопросы по тегам