Stellen wir uns vor, ich habe eine Groups and Users-Methode, und wenn der Benutzer einer Gruppe beitreten möchte, rufe ich die groupsService.AddUserToGroup-Methode (group, user) auf. In DDD sollte ich group.JoinUser (user) machen, was ziemlich gut aussieht.
DDD empfiehlt Ihnen jedoch auch, (zustandslose) Dienste zum Ausführen von Aufgaben zu verwenden, wenn die jeweilige Aufgabe zu komplex ist oder nicht in ein Entitätsmodell passt. Es ist in Ordnung, Dienste in der Domänenschicht zu haben. Die Dienste in der Domänenschicht sollten jedoch nur Geschäftslogik enthalten. Externe Aufgaben und Anwendungslogik (wie das Senden einer E-Mail) sollten hingegen den Domänendienst in der Anwendungsschicht verwenden, in den Sie beispielsweise einen separaten (Anwendungs-) Dienst einbinden können.
Das Problem tritt auf, wenn ich einige Validierungsregeln zum Hinzufügen eines Benutzers habe ...
Die Validierungsregeln gehören zum Domain-Modell! Sie sollten in den Domänenobjekten (Entitäten usw.) gekapselt sein.
... oder einige externe Aufgaben müssen gestartet werden, wenn Benutzer zur Gruppe hinzugefügt werden. Wenn Sie diese Aufgaben ausführen, hat die Entität externe Abhängigkeiten.
Ich weiß zwar nicht, um welche externen Aufgaben es sich handelt, aber ich gehe davon aus, dass es sich um das Senden einer E-Mail usw. handelt. Dies ist jedoch nicht wirklich Teil Ihres Domain-Modells. Es sollte in der Anwendungsebene liegen und dort imho gehandhabt werden. Sie können einen Dienst in Ihrer Anwendungsebene haben, der auf Domänendiensten und Entitäten zum Ausführen dieser Aufgaben ausgeführt wird.
Aber die Tatsache, dass eine Entität von einigen externen Diensten / Klassen abhängt, scheint mir nicht so gut und "natürlich" zu sein.
Es ist unnatürlich und sollte nicht passieren. Das Unternehmen sollte nichts über Dinge wissen, die nicht in seiner Verantwortung liegen. Services sollten zum Orchestrieren von Entitätsinteraktionen verwendet werden.
Wie gehe ich mit DDD richtig um?
In Ihrem Fall sollte die Beziehung wahrscheinlich bidirektional sein. Ob der Benutzer der Gruppe beitritt oder die Gruppe den Benutzer übernimmt, hängt von Ihrer Domain ab. Tritt der Benutzer der Gruppe bei? Oder wird der Benutzer einer Gruppe hinzugefügt? Wie funktioniert es in Ihrer Domain?
Auf jeden Fall haben Sie eine bidirektionale Beziehung und können so die Anzahl der Gruppen bestimmen, zu denen der Benutzer bereits im Benutzeraggregat gehört. Ob Sie den Benutzer an die Gruppe oder die Gruppe an den Benutzer übergeben, ist technisch unbedeutend, sobald Sie die verantwortliche Klasse festgelegt haben.
Die Validierung sollte dann von der Entität durchgeführt werden. Das Ganze wird von einem Dienst der Anwendungsebene aufgerufen, der auch technische Dinge erledigen kann, wie das Versenden von E-Mails usw.
Wenn die Überprüfungslogik jedoch sehr komplex ist, ist ein Domänendienst möglicherweise die bessere Lösung. In diesem Fall kapseln Sie die Geschäftsregeln ein und rufen Sie sie dann von Ihrer Anwendungsebene aus auf.
Ich würde das Problem der Validierung folgendermaßen angehen: Erstellen Sie einen Domänendienst mit dem Namen
MembershipService
:Der Konzerneinheit muss injiziert werden
IMemberShipService
. Dies kann auf Klassen- oder Methodenebene erfolgen. Nehmen wir an, wir machen das auf Methodenebene.Der Application-Service:
GroupService
kann mit derIMemberShipService
Constructor-Injection injiziert werden, die dann an dieJoinUser
Methode derGroup
Klasse übergeben werden kann.quelle