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.