Ich frage mich Folgendes: Angenommen, wir erstellen ein System, in dem Filterfunktionen erforderlich sind, um nach einer Entität zu suchen. Beispielsweise möchte man die Filterung möglicherweise auf eine Tabelle anwenden, in der die Entitäten aufgelistet sind, um etwas zu finden, oder damit einen Bericht über eine gefilterte Menge erstellen.
Der Punkt ist: Wir brauchen irgendwo eine Filterlogik. Ein schlechter Weg, dies zu tun, wäre, die Filterlogik bei Bedarf zu replizieren. Ich habe das einmal gemacht und es ist eine schreckliche Idee.
Andererseits glaube ich, dass es eine Methode geben sollte, die Filter(FilteringOptions filteringOptions)
entwickelt wurde, um die Filteroperation durchzuführen und die gefilterte Liste von Entitäten zurückzugeben.
Nun, IMHO, ist die Filterlogik eine Art Geschäftslogik. Die Geschäftsexperten sind diejenigen, die wissen, wie die Filterung erfolgt, welche Dinge gefiltert werden und wie. Aus diesem Grund glaube ich, dass sich die Filterlogik in der Domänenschicht befinden sollte.
Ich habe dafür zwei Möglichkeiten gefunden: Einbetten der Filtermethode in das entsprechende Repository für diese bestimmte Entität oder Erstellen eines Domänendienstes, EntityNameSearchService
der das Repository für die Filterung benötigt.
Ich bin immer noch verwirrt, welcher der bessere Weg wäre. Also, wenn ich versuche, DDD richtig zu verwenden, wo sollte diese Filterlogik sein? Im Repository oder in einem separaten Dienst?
quelle
Get*
Methode wiederverwenden und andere oder benutzerdefinierte Filter in die Service-Schicht einführen. Die Entscheidung liegt größtenteils bei Ihnen.Antworten:
Sie sollten beachten, dass dieser Punkt, an dem sich Ihre Anwendungsfälle zum Filtern auf Lese- und nicht auf Schreibvorgänge konzentrieren. Dies ist das normale Muster. Ein Schreibvorgang wird normalerweise an einen bestimmten aggregierten Stamm in Ihrer Domäne gerichtet.
Wenn Sie einen Lesevorgang durchführen, kümmern Sie sich nicht wirklich um Aggregate - Sie kümmern sich nicht um die Durchsetzung der Geschäftsinvariante, weil Sie nicht wirklich versuchen, etwas zu ändern. Sie kümmern sich nur um den Staat.
Dies kann bedeuten, dass es sinnvoll ist, das Domänenmodell vollständig zu umgehen.
Nur etwas zum Nachdenken.
Ja und nein. Sie greifen auf die allgegenwärtige Sprache zurück, um den Filter zu beschreiben. Sie verwenden also definitiv das Domain-Vokabular.
Aber Sie haben kein "Verhalten", insofern Sie das Buch der Aufzeichnungen nicht wirklich modifizieren, so dass Sie nicht die Invariante haben, über die Sie sich Sorgen machen müssen.
Sie sind der Idee der "Spezifikation" sehr nahe . Es ist im Grunde ein Prädikat, mit dem ein Repository identifizieren kann, welche Artefakte bestimmten Kriterien entsprechen.
Es gibt einige Fallen zu beachten. Greg Young hat sie vor einiger Zeit angesprochen , aber ich werde sie hier zusammenfassen.
Erstens ist die Abstraktion, ein Prädikat für eine Sammlung auszuführen, O (N). Sie werden wahrscheinlich etwas Schöneres wollen, besonders wenn Ihr Persistenzspeicher bei der Indizierung klug ist. Ihre Persistenzkomponente möchte sie wahrscheinlich in eine implementierungsspezifische Einschränkung umwandeln können (Beispiel: Nehmen Sie eine Spezifikation und wandeln Sie sie in eine where-Klausel für eine vorbereitete Anweisung um).
Zweitens ist eine Schnittstelle ein Mittel zum Dokumentieren des Vertrags, der von der Persistenzkomponente bedient wird. "Machen Sie das Implizite explizit" - Wenn Sie beschreiben, was Sie wirklich benötigen, sagt Ihnen die Benutzeroberfläche etwas darüber, welche Eigenschaften für Ihren Datenspeicher wichtig sind, sodass Sie einen einzigen Ort finden, an dem Sie nach einer Alternative suchen können Laden ist geeignet.
(Natürlich kann die Implementierung dieser Schnittstelle nur ein Adapter sein, der die Spezifikation aus den Methodenargumenten erstellt und diese weiterleitet. Das ist in Ordnung, Sie haben die tatsächliche Anforderung erfasst.)
quelle