Was sollte ein Repository wirklich tun?

14

Ich habe viel über das Repository-Muster gehört, aber ich habe nicht verstanden, was ein Repository wirklich tun sollte. Wenn ich sage "Was ein Repository wirklich tun sollte", mache ich mir hauptsächlich Gedanken darüber, welche Methoden es bereitstellen sollte. Soll ein Repository beispielsweise wirklich CRUD-Methoden oder eine andere Methode bereitstellen?

Ich meine, sollten die Repositorys Geschäftslogik enthalten, oder sollten sie einfach die Logik enthalten, um mit dem Datenspeicher zu kommunizieren und die zu speichernden oder zu ladenden Entitäten zu verwalten?

Ich habe auch gehört, dass Repositorys Persistenz-Einheiten für Aggregate sind. Aber wie ist das Ich verstehe nicht, wie das in der Praxis funktioniert. Ich dachte, wir sollten nur eine Schnittstelle haben, IRepositorydie die CRUD-Methoden enthält, und dann würde die Implementierung für jede Entität einfach die Logik zum Speichern und Abrufen eines solchen Typs aus dem Datenspeicher enthalten.

user1620696
quelle
4
"sollten die Repositories Geschäftslogik enthalten" - nein.
ozz
1
Hier ist meine Antwort auf eine verwandte Frage zu SO
Eric King
2
Ich denke, Sie werden vom Wort "sollte" erfasst - das Repository ist ein bestimmtes Muster, Sie sprechen, als gäbe es eine Möglichkeit, ein Repo zu erstellen, die die beste Art ist , ein Repo zu erstellen. Dies ist ein Missverständnis, da es nur einen Weg gibt, ein Repo zu machen, alles andere wäre kein Repo. Als solches hat das Repo-Muster Stärken und Schwächen, aber es gibt keine vielfältigen Ansätze für ein Repo. Es gibt jedoch mehrere Möglichkeiten, mit Daten zu interagieren, von denen ein Repo nur eine ist. Lesen Sie hier einige andere Dateninteraktionsansätze
Jimmy Hoffa

Antworten:

13

Nun, Sie können ein gutes Beispiel in der sehen Spring Data Framework sehen, das auf dem Konzept von Repositorys basiert.

Dort sehen Sie, dass Repositorys nur den Datenspeicher behandeln und selten Geschäftslogik enthalten (diese ist für die Service-Schicht reserviert). Wenn Sie sich zum Beispiel das Design ansehen, werden Sie feststellen, dass sie eine CRUDRepository- Schnittstelle haben, die Methoden zum Erstellen, Zerstören und Wiederherstellen von Entitäten (unter anderem) bereitstellt. Es gibt auch ein PagingAndSortingRepository , das zusätzliche Funktionen für genau das, Sortieren und Paging-Ergebnisse usw. usw. hinzufügt.

Dieses Framework ist vielleicht ein guter Ort, um ein gutes Repository-Design zu studieren.

Soweit mir bekannt ist, stammen viele der vom Spring Data Framework implementierten Konzepte aus einem großartigen Buch mit dem Titel Domain-Driven Design: Komplexität im Herzen von Software bewältigen . Das Buch enthält einen vollständigen Abschnitt zum Repository-Design.

Sie können eine Kopie davon erhalten.

Ein kleiner Auszug aus dem Buch erklärt:

Das REPOSITORY-Muster ist ein einfaches konzeptionelles Framework, um diese Lösungen zusammenzufassen und unseren Modellfokus wieder herzustellen.

Ein REPOSITORY repräsentiert alle Objekte eines bestimmten Typs als konzeptionelle Menge (normalerweise emuliert). Es verhält sich wie eine Sammlung, verfügt jedoch über umfangreichere Abfragemöglichkeiten. Objekte des entsprechenden Typs werden hinzugefügt und entfernt, und die Maschine hinter dem REPOSITORY fügt sie ein oder löscht sie aus der Datenbank. Diese Definition umfasst eine Reihe zusammenhängender Verantwortlichkeiten, um den Zugang zu den Wurzeln von AGGREGATES vom frühen Lebenszyklus bis zum Ende zu ermöglichen.

Clients fordern Objekte vom REPOSITORY an, indem sie Abfragemethoden verwenden, die Objekte basierend auf vom Client festgelegten Kriterien auswählen, normalerweise dem Wert bestimmter Attribute. Das REPOSITORY ruft das angeforderte Objekt ab und kapselt die Maschinerie von Datenbankabfragen und die Zuordnung von Metadaten. REPOSITORIES kann eine Vielzahl von Abfragen implementieren, die Objekte basierend auf den Kriterien auswählen, die der Client benötigt. Sie können auch zusammenfassende Informationen zurückgeben, z. B. die Anzahl der Instanzen, die bestimmte Kriterien erfüllen. Sie können sogar zusammenfassende Berechnungen zurückgeben, z. B. die Summe aller übereinstimmenden Objekte eines numerischen Attributs.

Ein REPOSITORY entlastet den Kunden enorm. Er kann nun mit einer einfachen, aufschlussreichen Benutzeroberfläche kommunizieren und nach den Anforderungen im Hinblick auf das Modell fragen. Um all dies zu unterstützen, ist eine sehr komplexe technische Infrastruktur erforderlich, die Schnittstelle ist jedoch einfach und konzeptionell mit dem Domänenmodell verbunden.

Deshalb:

Erstellen Sie für jeden Objekttyp, der globalen Zugriff benötigt, ein Objekt, das die Illusion einer speicherinternen Sammlung aller Objekte dieses Typs vermitteln kann. Richten Sie den Zugriff über eine bekannte globale Schnittstelle ein.

Stellen Sie Methoden zum Hinzufügen und Entfernen von Objekten bereit, die das tatsächliche Einfügen oder Entfernen von Daten in den Datenspeicher kapseln. Stellen Sie Methoden bereit, die Objekte basierend auf bestimmten Kriterien auswählen und vollständig instanziierte Objekte oder Sammlungen von Objekten zurückgeben, deren Attributwerte die Kriterien erfüllen, wodurch die eigentliche Speicher- und Abfragetechnologie gekapselt wird. Geben Sie REPOSITORIES nur für AGGREGATE-Roots an, auf die tatsächlich direkt zugegriffen werden muss. Konzentrieren Sie sich auf das Modell, delegieren Sie den gesamten Objektspeicher und greifen Sie auf die REPOSITORIES zu.

edalorzo
quelle
4

Es sollte weder eine direkte CRUD-Schnittstelle noch Geschäftslogik bieten. Es vermittelt zwischen Geschäftslogik und Datenbank. Die Schnittstelle sollte in Geschäftslogik ausgedrückt sein, aber keine Geschäftslogik selbst ausführen, eher wie ein Geschäftslogikgrundelement. Angenommen, Sie möchten ein E-Mail-System erstellen, Sie haben Benutzer und Nachrichten. Ihr Repository würde grundlegende CRUD-Operationen für Benutzer und Nachrichten bereitstellen, aber es würde auch gefilterte Ansichten von Nachrichten wie GetUsersNewMessages (Benutzer) oder GetSearchedMessages (Benutzer, searchTerms) bereitstellen.

Die Idee ist, dass das Repository verbirgt, wie Speicher implementiert wird, und eine saubere Schnittstelle bereitstellt, die einen schnellen und flexiblen Zugriff auf die Daten ermöglicht. Wenn Sie die Abläufe auf einem hohen Niveau halten, was passieren soll und nicht, bedeutet dies, dass Sie mehr Flexibilität haben, um sie auf die für den zugrunde liegenden Hintergrundspeicher beste Weise zu implementieren.

Steinmetalle
quelle