2017-10-01 1 views
3

Ich arbeite an einem Aggregat, wo bestimmte Verhaltensweisen von mehreren Rollen innerhalb der Anwendung durchgeführt werden können. Aber bevor das passiert, passiert ziemlich komplexe Validierung. Diese Validierung unterscheidet sich je nach Rolle. In der Regel bedeutet dies, dass verschiedene Konfigurationseinstellungen überprüft werden, um festzustellen, ob die Aktion ausgeführt werden kann.Wie injiziere ich Verhalten in ein Aggregat?

Also, als Beispiel: sagen wir, ich habe eine Bestellung, zu der ich OrderLines hinzufügen kann. Wenn ich Rolle Mitarbeiter habe, könnte ich bis zu € 100, - bestellen und wenn ich Rolle Käufer habe, kann ich bis zu € 1000, - bestellen.

Sie können dies lösen, indem Sie der addOrderLine-Methode die Benutzerinstanz bereitstellen, die jedoch den Benutzerkontext in den Bestellkontext leckt. Die nächste logische Sache, und das ist, was ich getan habe, ist es, diese Validierungslogik in den Methodenaufruf zu injizieren. Ich bin diese Methoden Richtlinien fordern und die richtige Politik in dem Application-Service-instanziiert, wie ich die entsprechenden Benutzer Informationen dort zur Verfügung habe:

<?php 
class Order { 
    public function addItem(OrderPolicy $policy, Item $item, int $amount) { 
     if (!$policy->canPurchase($item->getPrice() * $amount)) 
      throw new LimitExceededException(); 

     /* add item here */ 
} 

class OrderService { 
    public function addItem(User $user, $orderId, $itemId, int $amount) { 
     $order = $this->orderRepo->getForUser($user, $orderId); 
     $item = $this->itemRepo->get($itemId); 
     $policy = $this->getOrderPolicyFor($user); 

     $order->addItem($policy, $item, $amount); 
    } 
} 

class PurchaserOrderPolicy 
{ 
    function canPurchase($amount) { 
     return ($amount <= 1000); 
    } 
} 

Dies scheint in Ordnung, aber jetzt scheint es mir, meine Bestellung Zusammenhang hat Logik basierend auf Benutzerrollen (die Richtlinienklassen), über die sie nicht informiert werden sollte.

Bietet DDD andere Möglichkeiten, damit umzugehen? Vielleicht Spezifikation? Scheint das gut? Wo gehören die Policy-Klassen?

+0

Ich würde vorschlagen, zu Logik zum Dienst zu wechseln und es nicht zu Ihrem Aggregat zu propagieren. Führen Sie die Überprüfung im OrderService durch und wenn der Benutzer das Objekt nicht hinzufügen darf, wird eine Ausnahme vom Service ausgelöst. –

Antwort

2

Es scheint, dass Sie zwei Subdomains/Systeme beteiligt sind: System bestellen und System kaufen Politik. Sie müssen das Ding getrennt halten, Ihr Darm war richtig. Dies bedeutet, dass die Validierung über den maximalen Bestellwert auf eine eventuell konsistente Art und Weise im Vergleich zum tatsächlichen Hinzufügen des Artikels geprüft wird. Sie können dies vorher tun (Sie versuchen, eine ungültige Bestellung zu verhindern) oder nachher (Sie versuchen, eine ungültige Bestellung wiederherzustellen).

Wenn Sie es vorher tun, dann könnte der Anwendungsdienst das orchestrieren und die Bestellung ablehnen.

Wenn Sie es tun, nachdem dann könnte man dies als einen Prozess implementieren und haben eine ApplyPoliciesToOrdersSaga, die dem Ereignis hören (wenn Sie eine ereignisgesteuerte Architektur haben) oder das läuft als geplante Aufgabe/Cron-Job und überprüft alle Befehle gegen die Richtlinien (in einer klassischen Architektur).

+0

Also, wenn Sie dies zuvor behandelt haben, würden Sie die Richtlinien außerhalb des Aggregats aufrufen und in diesem Fall also im App-Service? Ich habe es in das Aggrat aufgenommen, da es scheint, dass dies eine der Invarianten ist, die es schützen sollte. Wie siehst du das? – NSSec

+0

@NSSec Ja, ich würde einen Abfrageservice von dem anderen System aufrufen und wenn das Element erlaubt ist, dann rufe das lokale Aggregat auch auf. Das Richtlinienmuster (falls vorhanden) scheint in Ordnung zu sein, aber wie gesagt, Sie verwenden es im anderen System. –

Verwandte Themen