2017-01-12 4 views
6

Ich habe gerade eben Greg Youngs auf Ereignis-Sourcing sprechen, aber ich bin verwirrt, wo Business-Logik passt in ein einfaches Beispiel:.Event Sourcing - wo passt Domain Logic?

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

den Gutscheincode gegen die Artikel Warenkörben berechnet und das Ergebnis davon als Ereignis gespeichert. Ich verstehe "PromotionalCodeAddedEvent" würde vielleicht Sinn machen, aber wo passiert die Mathematik? Ich denke:

Dann endet das Ergebnis nirgends und das Read Model müsste die Berechnungen durchführen.

Ich verstehe das Konzept nicht vollständig, jede Hilfe wäre großartig.

+0

Wenn es hilfreich ist, ich eine Blog-Post habe, die eine typische CQRS und ES-Anwendung legt und wie sie paßt zusammen. Sie können es hier sehen [CQRS + Event Sourcing - Eine Schritt für Schritt Übersicht] (http://danielwhittaker.me/2014/10/02/cqrs-step-step-guide-flow-type-application/) – Codescribler

Antwort

1

Sie können z. B. ein zweites Ereignis wie PromotionalCodeApplied auslösen, das die Berechnungsergebnisse enthält.

Das Read-Modell muss dann nur das vorberechnete Ergebnis verwenden.

+0

Hallo Alexander würde das ItemAddedEvent nach dem Hinzufügen jedes Artikels auch den vollen Preis des Einkaufswagens enthalten? – TBD

+0

Ja, das würde funktionieren, oder Sie möchten ein separates "ShoppingCardTotalPriceChanged" -Ereignis verwenden, das ausgelöst wird, wenn Elemente ODER Promocodes hinzugefügt werden. –

0

Dies ist, wo ich gerne Ereignisse von Befehlsmethoden zurückgeben.

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; 
} 

Jetzt Ihr Lese Modell hat auf die entsprechenden Werte Zugang: Als Alexander Langer erwähnt, würden Sie die „Mathematik“ und geben die entsprechenden Event (s) gelten.

3

Etwas so scheinbar Einfaches wie ein Promotion-Code kann tatsächlich ein ziemlich komplexer Anwendungsfall sein. Dies ist in erster Linie darauf zurückzuführen, dass ein Promotion-Code eine Logik ist, die (normalerweise) von einem oder mehreren Geschäftsanwendern verwaltet wird, obwohl er auch innerhalb der Domäne selbst gehört. In diesem Sinne ist es nicht traditionell. Es gibt mehrere Möglichkeiten, damit umzugehen, und was ich skizzieren möchte, wäre nur meine persönliche Herangehensweise.

Aus Gründen der Argumentation, davon ausgehen, dass Sie eine einfache Reihe von bekannten Promotion-Codes haben, wie zum Beispiel:

  • X% Rabatt auf Kauf, mit oder ohne Mindestkauf
  • $ X Aus Kauf, mit oder ohne Mindestkauf

Wir haben einige Annahmen getroffen werden können, aber auch:

  • AP romotional-Code hat ein Startdatum
  • ein Gutscheincode ein Enddatum

Die Anwendung eines Promotion-Code hat, kann schwierig sein. Betrachten Sie die zwei Szenarien, die wir definiert haben. "$ X Off Purchase" ist vergleichsweise einfach, da es sich um einen festen Betrag handelt. "X% Off Purchase" ist jedoch komplexer. Wenn wir nur den festen Betrag hätten, könnten wir den Rabatt auf den Einkaufswagen anwenden, sobald die Schwellenwerte erreicht sind. Wenn der Benutzer mit einem prozentualen Rabatt zwei Artikel hinzufügt, einen Gutscheincode hinzufügt und dann einen weiteren Artikel hinzufügt, wird die Werbeaktion bereits "angewendet".

Aus diesem Grund würde ich persönlich nur einen Gutscheincode an einen Einkaufswagen "anhängen". Warum? Der Grund dafür ist, dass ich an der Kasse wahrscheinlich davon ausgehen kann, dass ein Einkaufswagen verwendet wird, um eine Bestellung zu erstellen. Bis dahin ist der Inhalt des Wagens fließend.Die Aktion eines Benutzers gegen den Einkaufswagen ändert den Gesamtwert des Einkaufswagens sowie den gesamten Rabatt unter Annahme eines nicht festgelegten Rabattbetrags. Es kann auch einen Rabatt als ungültig erklären, wenn ein Benutzer einen oder mehrere Artikel aus einem Einkaufswagen entfernt und der Gesamtwert des Einkaufswagens unter den Schwellenwert fällt, um den Rabatt anzuwenden.

So hätte ich eigentlich mehrere Befehle, die beteiligt wäre. Im Wesentlichen können alle Befehle, die sich auf den Wert des Einkaufswagens auswirken, den Rabattbetrag ändern. Zu diesem Zweck würde ich für den Rabatt Menge suchen werden für die Befehle neu berechnet, die:

  • ein Element hinzufügen in den Warenkorb gelegt
  • einen Artikel aus dem Warenkorb entfernen
  • Ändern Sie die Anzahl der Artikel in der Wagen
  • einen Gutscheincode in den Warenkorb in den Warenkorb gelegt angebracht
  • ändern Sie den Gutscheincode hinzufügen

Da diese alle sind operat Ich würde den Rabatt innerhalb des Aktionscodes selbst unter Beteiligung der im Warenkorb enthaltenen Daten berechnen. Es fühlt sich wie ein Promotion-Code wird ein Aggregat sein, diesen Pfad gehen. Also würde ich die Befehlshandler einen Domain-Service aufrufen lassen, der meinen Warenkorb mit den erforderlichen Informationen versorgen kann. Der Domain-Service lädt den Gutschein-Code und ich kann die Werbebuchungen in diesem Warenkorb übergeben, sodass der Rabattcode mir sagt, wie hoch der berechnete Rabatt sein würde. Dann werde ich das Ereignis generieren, das den neuen Wert des Einkaufswagens enthält, zusammen mit dem angepassten Wert (der Rabatt). Wenn Sie diesen Pfad durchgehen, liegt die Logik für die Berechnung eines Rabatts basierend auf Werbebuchungen in einem Einkaufswagen in der Verantwortung des Gutscheincodes.

Sie könnten stattdessen diese Verantwortung in den Warenkorb legen. Persönlich habe ich jedoch das Gefühl, dass die Kapselung der Domänenlogik innerhalb des Werbecodes selbst mehr Sinn ergibt. Ich habe erwähnt, dass es wahrscheinlich ist, dass Sie eine Bestellung aus einem Einkaufswagen generieren. Durch die Verwendung des Aktionscodes als Aggregat und mit der Logik, den Rabatt basierend auf den Werbebuchungen anzuwenden, haben wir eine einzige Wahrheit, nämlich wie wir einen Rabatt für Werbebuchungen berechnen - ob es sich um einen Einkaufswagen oder um einen Artikel handelt Bedingungen einer Bestellung.

+1

Joseph, danke für die Antwort, dass eine nette Idee und hat mir zum Nachdenken gegeben. – TBD

1

Ich verstehe "PromotionalCodeAddedEvent" wäre vielleicht sinnvoll, aber wo passiert die Mathematik?

Es sollte in Befehlen auftreten, die Änderungen am Einkaufswagen vornehmen. Jeder dieser Befehle ruft eine Methode wie RecalculateTotals() auf, in der alle Geschäftslogik gehostet wird.

Betrachten Sie den folgenden Pseudo-Code:

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 
}