DDD - Kann das Repository eines Aggregatstamms Aggregate speichern?

27

Ich verwende einen DDD-ähnlichen Ansatz für ein Greenfield-Modul einer vorhandenen Anwendung. Aufgrund der Architektur ist es nicht 100% DDD, aber ich versuche, einige DDD-Konzepte zu verwenden. Ich habe einen begrenzten Kontext (ich denke, das ist der richtige Begriff - ich lerne immer noch über DDD), der aus zwei Entitäten besteht: Conversationund Message. Konversation ist die Wurzel, da eine Nachricht ohne die Konversation nicht existiert und alle Nachrichten im System Teil einer Konversation sind.

Ich habe eine ConversationRepositoryKlasse (obwohl es eigentlich eher wie ein Gateway ist, verwende ich den Begriff "Repository"), die Konversationen in der Datenbank findet. Wenn eine Konversation gefunden wird, wird (über Fabriken) auch eine Liste von Nachrichten für diese Konversation erstellt (als Eigenschaft verfügbar gemacht). Dies scheint die richtige Vorgehensweise zu sein, da eine vollständige MessageRepositoryKlasse nicht erforderlich zu sein scheint, da sie nur vorhanden ist, wenn eine Konversation abgerufen wird.

Ist dies jedoch die Verantwortung des ConversationRepositorys, wenn es um das Speichern einer Nachricht geht, da es sich um die Gesamtwurzel der Nachricht handelt? Was ich meine ist, sollte ich eine ConversationRepository-Methode mit dem Namen haben, AddMessagedie eine Nachricht als Parameter annimmt und in der Datenbank speichert? Oder sollte ich ein separates Repository zum Suchen / Speichern von Nachrichten haben? Das logische Ding scheint ein Repository pro Entität zu sein, aber ich habe auch "Ein Repository pro Kontext" gehört.

Wayne Molina
quelle

Antworten:

25

Das Blaue Buch ist auf jeden Fall eine Lektüre wert, wenn Sie das Beste aus dem DDD-Ansatz herausholen möchten. DDD-Muster sind nicht trivial, und das Erlernen des Wesens der einzelnen Muster hilft Ihnen beim Überlegen, wann Sie welches Muster verwenden, wie Sie Ihre Anwendung in Ebenen unterteilen, wie Sie Ihre Aggregate definieren usw.

Die Gruppe von zwei Entitäten, die Sie erwähnen, ist kein beschränkter Kontext - es handelt sich wahrscheinlich um ein Aggregat. Jedes Aggregat verfügt über einen Aggregatstamm, eine Entität, die als einzelner Einstiegspunkt für das Aggregat für alle anderen Objekte dient. Es gibt also keine direkte Beziehung zwischen einer Entität und einer anderen Entität in einem anderen Aggregat, das nicht die Aggregatwurzel ist.

Repositories werden benötigt, um Entities zu finden, die durch das Durchqueren anderer Objekte nicht einfach zu erhalten sind. Repositorys enthalten normalerweise aggregierte Roots, es kann jedoch auch Repositorys von regulären Entitäten geben.

In Ihrem Beispiel scheint die Konversation die Gesamtwurzel zu sein. Vielleicht sind Gespräche der Ausgangspunkt Ihrer Anwendung, oder Sie möchten sie mit detaillierten Kriterien abfragen, damit sie durch einfaches Durchlaufen anderer Objekte nicht zufriedenstellend zugänglich sind. In einem solchen Fall können Sie ein Repository für sie erstellen, das dem Client-Code die Illusion einer Reihe von speicherinternen Konversationen verleiht, die direkt abgefragt, hinzugefügt oder gelöscht werden können. Nachrichten hingegen können leicht durch Durchlaufen einer Konversation abgerufen werden, und Sie möchten sie möglicherweise nicht nach detaillierten Kriterien abrufen, sondern nur alle Nachrichten einer Konversation gleichzeitig, sodass sie möglicherweise kein Repository benötigen.

ConversationRepository spielt eine Rolle bei der Beibehaltung von Nachrichten, jedoch keine so direkte Rolle, wie Sie es erwähnen. Also kein AddMessage () im ConversationRepository (diese Methode gehört eher in Conversation selbst), sondern jedes Mal, wenn das Repository eine Conversation beibehält, ist es eine gute Idee, die Nachrichten gleichzeitig beizubehalten, entweder transparent, wenn Sie ein ORM-Framework verwenden wie (N) Ruhezustand, Verwendung von Ad-hoc-SQL, wenn Sie dies wünschen, usw.

guillaume31
quelle
1
Wenn ein zusammengefasster Stamm wie "Unterhaltung" viele verschiedene Entitätstypen wie "Nachricht", "Dinge" und "Flügel" enthält, wissen Sie beim Speichern einer Unterhaltung, z. B. "ConversationRepo.save" (Unterhaltung), welche Entitäten darin benötigt werden gespeichert werden? Im obigen Poster-Beispiel müssen nur die Nachrichtenobjekte gespeichert werden. Durchlaufen Sie alle möglichen Sammlungen im Aggregatstamm, um Entitäten ohne IDs zu finden?
Chris-richards
3

Sie könnten das schaffen ConversationService und injizieren IConversationRepository und IMessageRepository in seinem Konstruktor. Verwenden Sie Repositorys für einfache CRUD-Vorgänge und Services für alles andere (Zwischenspeichern, Speichern von Logik usw.).

šljaker
quelle
1
ist es nicht logisch CRUD zu speichern?
Timothy Groote