Szenario:
Ein Kunde gibt eine Bestellung auf und gibt nach Erhalt des Produkts eine Rückmeldung zum Bestellvorgang.
Nehmen Sie die folgenden aggregierten Wurzeln an:
- Kunde
- Auftrag
- Feedback
Hier sind die Geschäftsregeln:
- Ein Kunde kann nur Feedback zu seiner eigenen Bestellung geben, nicht zu der eines anderen.
Ein Kunde kann nur dann eine Rückmeldung geben, wenn die Bestellung bezahlt wurde.
class Feedback { public function __construct($feedbackId, Customer $customer, Order $order, $content) { if ($customer->customerId() != $order->customerId()) { // Error } if (!$order->isPaid()) { // Error } $this->feedbackId = $feedbackId; $this->customerId = $customerId; $this->orderId = $orderId; $this->content = $content; } }
Nehmen wir nun an, das Unternehmen möchte eine neue Regel:
Ein Kunde kann nur dann eine Rückmeldung geben, wenn die
SupplierWare der Bestellung noch in Betrieb ist.class Feedback { public function __construct($feedbackId, Customer $customer, Order $order, Supplier $supplier, $content) { if ($customer->customerId() != $order->customerId()) { // Error } if (!$order->isPaid()) { // Error } // NEW RULE HERE if (!$supplier->isOperating()) { // Error } $this->feedbackId = $feedbackId; $this->customerId = $customerId; $this->orderId = $orderId; $this->content = $content; } }
Ich habe die Implementierung der ersten beiden Regeln im Feedback
Aggregat selbst platziert. Ich fühle mich wohl dabei, insbesondere angesichts der FeedbackTatsache , dass das
Aggregat alle anderen Aggregate nach Identität referenziert. Zum Beispiel zeigen die Eigenschaften der FeedbackKomponente an, dass sie von der Existenz der anderen Aggregate weiß
, daher fühle ich mich wohl, wenn sie auch den schreibgeschützten Zustand dieser Aggregate kennt .
Aufgrund seiner Eigenschaften hat das FeedbackAggregat jedoch keine Kenntnis von der Existenz des
SupplierAggregats. Sollte es also Kenntnis vom schreibgeschützten Zustand dieses Aggregats haben?
Die alternative Lösung zur Implementierung von Regel 3 besteht darin, diese Logik an die entsprechende Stelle zu verschieben CommandHandler. Dies scheint jedoch die Domänenlogik vom "Zentrum" meiner zwiebelbasierten Architektur zu entfernen.
Supplierwürde der Betriebszustand eines Aggregats nicht über ein OrderRepository abgefragt . Supplierund Ordersind zwei separate Aggregate. Zweitens gab es in der DDD / CQRS-Mailingliste eine Frage zum Übergeben von aggregierten Roots und Repositorys an andere aggregierte Root-Methoden (einschließlich des Konstruktors). Es gab verschiedene Meinungen, aber Greg Young erwähnte, dass es üblich ist, aggregierte Wurzeln als Parameter zu übergeben, während eine andere Person sagte, dass Repositories enger mit der Infrastruktur als mit der Domäne verbunden sind. ZB Repositorys "abstrakt in Speichersammlungen" und haben keine Logik.
Customernur zu einer eigenen Bestellung Feedback geben kann ( $order->customerId() == $customer->customerId()), müssen wir auch die Lieferanten-ID ( $order->supplierId() == $supplier->supplierId()) vergleichen. Die erste Regel schützt vor dem Benutzer, der falsche Werte angibt. Die zweite Regel schützt vor dem Programmierer, der falsche Werte liefert. Die Prüfung, ob der Lieferant tätig ist, muss jedoch entweder in der FeedbackEntität oder im Befehlshandler erfolgen. Wo ist die Frage?
