2015-05-25 5 views
7

~ TLDR: Ich implementiere eine CQRS + DDD-Lösung für eines meiner größeren Projekte, und ich frage mich, ob es wirklich einen Grund gibt, den meine Befehlshandler nicht direkt versenden können Der Befehl Objekte zu meinen Aggregaten, in einer kleinen Handvoll von Fällen, in denen das Befehlsobjekt datenreich ist? Ich kann keinen bestimmten Grund finden, warum dies eine Art Anti-Pattern wäre, und ich kann keine Meinungen finden, die sehr detailliert über diese Art von Design gehen.CQRS-Befehle direkt an Domänenobjekte übergeben

Hintergrund: Ich habe bereits CQRS-Systeme implementiert, und ich habe DDD-Anwendungen implementiert, aber nie CQRS + DDD in einer geeigneten dedizierten Anwendung von Eric Evans. Also frage ich, weil ich meine Aggregate nicht missbrauchen und meine Bewerbung auf Dauer verletzen möchte.

Ein Beispiel für mein Befehlsobjekt, das ziemlich viele Daten enthält, wäre ein Registrierungsbefehl, der 8+ Felder (Vorname, Nachname, Bevorzugter Name, Dob, Titel, Benutzername, Passwort, Abteilung usw.) aufnimmt. Es fühlt sich sehr umständlich an, eine Methode auf meinem Aggregat zu erstellen, die 8 Parameter hat, und die alternative Lösung, irgendeine Art von dto zu verwenden, und meinen Handler den Befehl dem dto zuzuordnen - entweder automatisch mit automapper oder inline - scheint unnötig und nicht wertsteigernde Abstraktion.

Ich sehe auch zukünftige Anwendungsfälle, in denen Befehle Daten reichen könnten (es wäre kein großer Prozentsatz von Befehlen, aber es würden immer noch ein paar sein), also möchte ich diesen scheinbar trivialen Aspekt korrigieren von Anfang an.

+0

Soweit ich mich erinnere, sagt DDD nicht genau, wie das Domain Model zu implementieren, aber CQRS tut. Kein Konflikt hier. Wie haben Sie einfache Befehlsobjekte an Aggregates übergeben? Ich nehme an, Sie haben eine Abstraktion/Schnittstelle, von der beide abhängen. – neleus

+0

Ich übergebe die Befehlsdaten (nicht das eigentliche Befehlsobjekt) über Parameter an das Aggregat. Der Befehl wird von einem Handler empfangen, der das Aggregat lädt und es einfach über eine entsprechend entworfene Methode weitergibt. Normalerweise ist es nur ein oder ein paar Parameter, so wie ich es mag, da ich glaube, dass ein gut entworfenes Aggregat Methoden haben sollte, die nur sehr wenige Parameter benötigen. Sonst verletzt es wahrscheinlich irgendwie SRP. Aber es gibt * einige * Randfälle, in denen viele Parameter erforderlich sein können. – AaronHS

+0

Haben Sie darüber nachgedacht, das gesamte Befehlsobjekt an das Aggregat zu übergeben? Es sieht einfach aus, keine Nachteile. – neleus

Antwort

10

Befehlsobjekte werden normalerweise in primitiven Typen ausgedrückt, während aggregierte Methodensignaturen in Domänenkonzepten ausgedrückt werden.

Die Tatsache, dass Sie dies nicht sofort erkannt haben, bedeutet wahrscheinlich, dass Sie viele Möglichkeiten verpasst haben, implizite Konzepte in Ihrer Domäne explizit zu machen.

"eine Registrierungsbefehl, der in 8+ Felder nimmt (Vorname, Nachname, bevorzugten Namen, dob, Titel, Benutzername, Passwort, Abteilung etc.)"

Was Sie schlagen sollten, ist, dass firstname und lastname könnte definitiv ein sinnvolles Ganzes bilden, wie new FullName(firstname, lastname) und ich bin sicher, dass es viele andere Fälle gibt, in denen Value Objects (VO) könnte oder sollte in Ihrer Domäne verwendet werden ... Username, Password, etc.? Durch die Verwendung von VOs zum Modellieren gemeinsam verwandter Dinge können Sie Ihr Modell besser beschreiben und die Anzahl der Argumente reduzieren, die Sie weitergeben müssen.

Dies macht daher Befehlsobjekte schlechte Kandidaten als aggregierte Methodenargumente. Wenn Sie diese Straße hinuntergehen, werden Sie definitiv Modellierungsmöglichkeiten verpassen.

+0

Das macht Sinn. Danke für die Antwort, sowie eine klare Erklärung für das * warum * – AaronHS

2

Stimmen Sie mit @plalx überein.

Take-Befehle als Aggregatmethodenargumente können dazu führen, dass zu viele Mapping-Codes in Aggregaten vorhanden sind: Zuordnen primitiver Typen zu Domänenobjekten, die besser aus den Domänenobjekten entfernt werden sollen.

Aber für einfachere Projekte, denke ich, es ist ein guter Starter.

Im Fall der Registrierung ist der beschränkte Kontext in der Regel eine unterstützende Domäne und die Komplexität kommt normalerweise von externer Integration (E-Mail-Benachrichtigung, Registrierung bei sozialen Konten usw.). In diesem Fall denke ich, dass die Integration von gebundenem Kontext wichtiger ist als die darin enthaltenen Modelle. So nehmen Sie Befehle als aggregierte Methodenargumente, die einen schnellen Start der Dinge ermöglichen und Zeit sparen, um sich auf Ihre Kerndomäne zu konzentrieren.

Verwandte Themen