Eine Filterlogik sollte sich in einem Repository oder in einem Service befinden?

9

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, EntityNameSearchServiceder 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?

user1620696
quelle
2
Wo ist die Filterlogik aus Sicht der Wartbarkeit und Benutzerfreundlichkeit für Sie am sinnvollsten?
Robert Harvey
Auf den ersten Blick schien es, dass im Repository, da es das Objekt ist, das unter anderem für das Abrufen der Entitäten verantwortlich ist. Andererseits muss die Filterlogik nicht nur beim Abrufen angewendet werden, sondern kann auf jede Liste von Entitäten angewendet werden. Wenn man etwas mehr darüber nachdenkt, enthält die Domänenschicht nur die Schnittstellen von Repositorys. Die eigentliche Implementierung liegt in einem Datenprojekt und muss mit dem tatsächlichen Persistenzmechanismus gekoppelt werden, während die Dienste in der Domäne implementiert werden. Unter diesem Gesichtspunkt erscheint es sinnvoller, einen Filterdienst zu erstellen.
user1620696
1
Das Filtern in der Service-Schicht kostet mehr Zeit als das Abrufen bereits gefilterter Daten aus dem Repository über eine gezielte Methode. Sie können jedoch die generische Get*Methode wiederverwenden und andere oder benutzerdefinierte Filter in die Service-Schicht einführen. Die Entscheidung liegt größtenteils bei Ihnen.
Andy

Antworten:

4

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.

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.

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.

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.

Andererseits glaube ich, dass es eine Methode wie Filter (FilteringOptions filteringOptions) geben sollte, mit der die Filteroperation ausgeführt und die gefilterte Liste der Entitäten zurückgegeben werden kann.

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.)

VoiceOfUnreason
quelle