2017-02-28 2 views
0

Ich habe ein Designproblem, das sich seit einiger Zeit in meinem Kopf herumdreht und ich finde keine gute Lösung dafür. Es geht um CQRS und Domänengrenzen.Zusätzliche Begrenzungsdaten bei der Befehlsausführung

Angenommen, ich habe einen Kontext, in dem es darum geht, Buchungen und folglich Ereignisse für ein System zu übernehmen. Das System ermöglicht es, eine einzelne Buchung mit einem einzelnen Ereignis zu verknüpfen (das ist bereits erledigt, keine Probleme) und wöchentliche Buchungen, die mit einer Sammlung von Ereignissen verknüpft sind. Wöchentliche Buchungen werden mit einem Wochentag vorgenommen (zusätzliche Daten sind nicht relevant); Eine wöchentliche Buchung hat immer einen Anfangs- und Endtag (ein halbes Jahr).

Das System hat auch zwei Arten von Tagen: normale Tage und keine Arbeitstage, an denen ein Ereignis nicht stattfinden kann.

Als Geschäftsanforderung möchten die Benutzer, dass das System für jede wöchentliche Buchung nur solche Ereignisse storniert, die nicht an Werktagen gehalten werden.

Tatsächlich werden Buchungen und Ereignisse in zwei Tabellen gespeichert. Ein Ereignis wird abgebrochen, wenn es mit einem speziellen Flag gespeichert wird. Ich habe keine Verbindung mit der Tabelle der Tage, weil ich sie nie in meinem Geschäftskontext verwendet habe. Als Geschäftsgrenze (mit anderen kleinen Daten, hier nicht relevant) funktionierte das bisher großartig.

Hier ist mein Problem: Um die Benutzeranforderung zu erfüllen (erstellen Sie eine Veranstaltung für jeden gelöschten Tag), brauche ich Informationen über alle Tage des halben Jahres (nur diejenigen am selben Wochentag sind genug). Aber um diese Informationen zu erhalten, wie kann ich fortfahren?

Meine mögliche Lösungen:

  1. laden alle Tage Halbjahr in der Root-Entität. Das könnte sehr schwer sein, und ich muss meine Geschäftsgrenze erweitern.
  2. Den Befehl vorverarbeiten und einen mit zusätzlichen Informationen erstellen. Es wäre ein Befehlsbefehl, etwas, von dem ich gelesen habe, dass es gefährlich ist. Das ist genug für mich.
  3. Erweitern Sie den Befehl mit der Liste der ungültigen Tage. Wie überprüfe ich, dass ein Tag ungültig ist? Ich muss auf Daten außerhalb meiner tatsächlichen Grenze zugreifen, das ist das gleiche wie 1.
  4. Erstellen Sie einen Dienst, der im Befehlshandler verwendet wird, um die Liste der nicht arbeitenden Tage abzurufen. Die Tageskontextinformationen würden in einem gemeinsamen (oder gemeinsamen) Kontext verschoben werden.
  5. Erstellen Sie einen Ereignis-Listener für wöchentliche Ereignisse. Wenn ein wöchentliches Ereignis erstellt wird, lädt es die Liste der nicht arbeitenden Tage (für diesen Wochentag dieses halben Jahres) und löst eine Folge von Befehlen aus, um diese bestimmten Tage abzubrechen. Dies würde die Grenzen versiegeln, keine zusätzlichen Daten zu einem gemeinsamen Kontext hinzufügen und denselben Code für zusätzliche Zwecke wiederverwenden (Ereignis abbrechen).

Welche wäre die beste Lösung?

Antwort

1

Lackmus-Test: Fragen Sie Ihre Interessenvertreter, ob es jemals passiert, dass ein Arbeitstag zu einem arbeitsfreien Tag wird und was an diesen Tagen für wöchentliche Buchungen passieren soll. Es kommt auch vor, dass ein arbeitsfreier Tag zu einem Arbeitstag wird und was bei Buchungen auf diese Tage passieren soll.

Erstellen Sie einen Ereignis-Listener für wöchentliche Ereignisse. Wenn ein wöchentliches Ereignis erstellt wird, lädt es die Liste der nicht arbeitenden Tage (für diesen Wochentag dieses halben Jahres) und löst eine Folge von Befehlen aus, um diese bestimmten Tage abzubrechen. Dies würde die Grenzen versiegeln, keine zusätzlichen Daten zu einem gemeinsamen Kontext hinzufügen und denselben Code für zusätzliche Zwecke wiederverwenden (Ereignis abbrechen).

Schließen, basierend auf meinem Verständnis von dem, was Sie geschrieben haben.

In meinen Augen haben Sie wirklich zwei verschiedene Aggregate; Sie haben die Definition der wöchentlichen Buchung, und Sie haben tägliche Zeitpläne, die Ereignisse von verschiedenen Buchungen sammeln.

Wenn Sie eine Buchung erstellen, sind Ihre Eingaben ein Startdatum und Enddatum, einen Tag in der Woche, und wahrscheinlich einen Domain-Service, der eine Liste von Tagen der Woche in diesem Bereich zurückkehren kann. Denken Sie an Zeitplan oder Route - wir definieren die Kandidatentage für diese spezielle Buchung.

Wenn Sie eine neue Buchung sehen, löst Ihr Ereignis-Listener einen Befehl für das Zeitplanaggregat für diesen bestimmten Tag aus und fügt das von der täglichen Buchung angeforderte Ereignis hinzu. Da der Zeitplan weiß, ob es sich um einen "arbeitsfreien Tag" handelt oder nicht, kann er jedes dieser Ereignisse als geplant oder abgebrochen markieren (wenn Sie möchten, dass diese Informationen explizit sind, können Sie dies durch den Status des Arbeitstages implizieren) in einigen Systemen).

Leere Zeitpläne können im Voraus erstellt werden oder bei Bedarf mithilfe eines generischen Rezepts, um festzustellen, ob sie Arbeitstage sind oder nicht, und können Änderungen an ihrem eigenen Arbeitsstatus unterstützen, wenn dies Teil Ihrer aktuellen Domäne ist.

Die wichtigsten Ideen hier sind, dass nicht arbeitende Tage ein Teil Ihres Domain-Modells sind, und da sie mehrere Buchungsobjekte umfassen, sind sie eindeutig eine Entität, die außerhalb des Buchungsaggregats sitzt.

+0

Daher, wenn ich Ihren Vorschlag richtig verstanden habe, ist die letzte Option die beste. Zwei Aggregate mit zwei verschiedenen Zwecken und ein Ereignis-Listener, der die wöchentliche Buchung mit der Liste der nicht erlaubten Ereignisse "aktualisiert". –

Verwandte Themen