2017-01-12 3 views
6

Я только наблюдал Грег Янгс говорить на Event Sourcing, но я запутался, где бизнес-логика укладывается в простой пример:.Event Sourcing - где находится логика домена?

1) Shopping Cart Created 
2) Item Added 
3) Item Added 
4) Promotional Code - 20% Off 

ли промокод рассчитанный по отношению к пунктам торговые тележки и результат которого сохраняется как событие. Я понимаю, что «PromotionalCodeAddedEvent» может иметь смысл, но где же происходит математика? Я думаю:

public void AddPromotionalCode(PromotionalCode code) 
{ 
    //perform calculation against shopping cart items. 
    //if valid 
    ApplyChanges(cmd); 
} 

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

Я не совсем понимаю концепцию, любая помощь будет отличной.

+0

Если это полезно у меня есть сообщение в блоге, который выкладывает типичные CQRS и применение ES и как она вписывается вместе. Вы можете увидеть его здесь [CQRS + Event Sourcing - шаг за шагом обзора] (http://danielwhittaker.me/2014/10/02/cqrs-step-step-guide-flow-typical-application/) – Codescribler

ответ

1

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

Прочитанная модель тогда просто должна использовать предварительно вычисленный результат.

+0

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

+0

Да, это сработает или вы захотите использовать отдельное событие «ShoppingCardTotalPriceChanged», которое возникает при добавлении элементов или промокодов. –

0

Здесь я хочу возвращать события из методов команды. Как уже упоминалось Александр Лангер, вы бы применить «математику» и возвращает соответствующее событие (ы):

public PromotionalCodeApplied AddPromotionalCode(PromotionalCode code) 
{ 
    //perform calculation against shopping cart items. 
    var promotionalCodeApplied = new PromotionalCodeApplied(code.VoucherNumber, discountAmount, DateTime.Now); 

    On(promotionalCodeApplied); 

    return promotionalCodeApplied; 
} 

public void On(PromotionalCodeApplied promotionalCodeApplied) 
{ 
    _voucherNumber = promotionalCodeApplied.VoucherNumber; 
    _discountAmount = promotionalCodeApplied.DiscountAmount; 
    _discountDate = promotionalCodeApplied.DateAppllied; 
} 

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

3

Что-то вроде простенького, как промо-код, на самом деле может быть довольно сложным вариантом использования. Прежде всего, это связано с тем, что промокод является логикой, которая (как правило) поддерживается одним или несколькими бизнес-пользователями, тогда как она также принадлежит внутри домена. Это нетрадиционно, в этом смысле. Есть несколько способов справиться с этим, и то, что я опишу, будет просто моим личным подходом.

Ради аргумента, предположим, что у вас есть простой ряд известных рекламных кодов, таких как:

  • X% Off Покупка, с или без минимальной покупки
  • $ X Off Покупка, с или без минимальной покупки

Мы можем сделать некоторые предположения, а также:

  • А.П. romotional код имеет начальную дату
  • промокод имеет дату окончания

Применение промо-кода может быть сложно. Рассмотрим два сценария, которые мы определили. «$ X Off Purchase» сравнительно прост, так как фиксированная сумма. Однако покупка «X% Off Purchase» сложнее. Если бы у нас была только фиксированная сумма, мы могли бы применить скидку к тележке, как только будут достигнуты любые пороговые значения. Если скидка на процентную ставку, если пользователь должен добавить два элемента, добавьте промо-код, а затем добавьте еще один элемент, продвижение будет уже «применено».

Из-за этого я лично лично «приложил» рекламный код к тележке. Зачем? Причина в том, что в момент проверки я могу предположить, что тележка будет использоваться для создания заказа. До этого времени содержимое тележки было жидким.Действие пользователя против корзины изменит общее значение корзины, а также общую скидку при допущении нефиксированной скидки. Он также может сделать скидку недействительной, если пользователь удалит один или несколько предметов из корзины, а общая стоимость корзины опустится ниже порога, чтобы применить скидку.

Итак, у меня было бы несколько команд, которые были бы задействованы. По сути, любые команды, которые влияют на стоимость корзины, могут изменить сумму скидки. С этой целью, я искал бы сумму скидки будет пересчитана для команд, которые:

  • Добавить товар в корзину
  • Удаление элемента из корзины
  • изменить количество элементов в телега
  • Добавить промокод в корзину
  • Измените скидочное прикрепленную к телеге

Поскольку все они являются Operat против телеги, я бы подсчитал скидку в рамках промокода, сам с участием данных, содержащихся в тележке. Это чувствует, что, как промокод, будет агрегатом, идя по этому пути. Таким образом, я бы обработчикам команд вызывать службу домена, которая может предоставить моей телеге необходимую информацию. Эта служба домена будет загружать промокод, и я собираюсь пройти в позициях этой корзины, чтобы промокод подскажет мне, какой будет рассчитанная скидка. Затем я собираюсь создать событие, которое содержит новое значение корзины, а также скорректированное значение (скидка). Идя по этому пути, логика расчета скидки, основанная на позициях в корзине, несет ответственность за промо-код.

Вы можете поместить эту ответственность в корзину, вместо этого. Лично, однако, мне кажется, что инкапсуляция логики домена в промокод, сама по себе, имеет больше смысла. Я упомянул, что вполне вероятно, что вы создадите заказ из корзины. Имея промокод в качестве совокупности и содержащий логику применения скидки на основе позиций, мы имеем единственную истину в том, как мы вычисляем скидку на позиции - будь то с точки зрения тележки или в условия заказа.

+1

Джозеф, спасибо за ответ, что хорошая идея и дал мне пищу для размышлений. – TBD

1

Я понимаю, что «PromotionalCodeAddedEvent» может иметь смысл, но где же происходит математика?

Это должно произойти в командах, которые вносят изменения в корзину покупок. Каждая такая команда вызовет некоторый метод, например RecalculateTotals(), где будет размещена вся бизнес-логика.

Рассмотрим следующий псевдокод:

public void AddPromotionalCode(PromotionalCode code) 
{ 
    var @event = new PromotionalCodeAdded(code); 
    var amount = RecalculateTotalAmount(extraEvent: @event); 
    @event.TotalAmount = amount; 
    _eventStore.Publish(@event); 
} 

decimal RecalculateTotalAmount(IEvent extraEvent) 
{ 
    var relatedEventTypes = new[] { typeof(PromotionalCodeAdded), typeof(ShoppingCartCreated), typeof(ItemAdded) }; 
    var events = _eventStore.ReadEventsOfTypes(relatedEventTypes); 
    var events = events.Concat(new[] { extraEvent }); 

    //calculation logic goes here based on all related events 
} 
Смежные вопросы