Co naprawdę powinno zrobić repozytorium?

15

Słyszałem wiele wzorców repozytoriów, ale zupełnie nie rozumiałem, co tak naprawdę powinno robić repozytorium. Kiedy mówię „co naprawdę powinno zrobić repozytorium”, martwię się głównie o to, jakie metody powinien on zapewnić. Na przykład, czy repozytorium naprawdę powinno zapewniać metody CRUD, czy powinno zapewniać jakąś inną metodę?

Mam na myśli, czy repozytoria powinny zawierać logikę biznesową, czy powinny po prostu zawierać logikę do komunikowania się z magazynem danych i zarządzania podmiotami, które mają być zapisywane lub ładowane?

Słyszałem również, że repozytoria są jednostkami trwałości agregatów. Ale jak to jest? Nie rozumiem, jak to działa w praktyce. Pomyślałem, że powinniśmy mieć tylko jeden interfejs, IRepositoryktóry zawiera metody CRUD, a następnie dla każdego podmiotu implementacja po prostu zawiera logikę zapisywania i pobierania tego typu z magazynu danych.

użytkownik1620696
źródło
4
„czy repozytoria zawierają logikę biznesową” - nie.
ozz
1
Oto moja odpowiedź na powiązane pytanie dotyczące SO
Eric King
2
Myślę, że przyłapujesz się na słowie „powinien” - repozytorium jest specyficznym wzorcem, mówisz tak, jakby repo powinno być zrobione, które jest najlepszym sposobem na wykonanie repo; jest to błędne przekonanie, ponieważ istnieje tylko jeden sposób na wykonanie repo, nic innego nie byłoby repo. W związku z tym wzór repozytorium ma swoje mocne i słabe strony, ale nie ma wielu podejść do repo. Nie jednak liczne sposoby komunikowania się z danymi, z których repo jest tylko jedna. Przeczytaj tutaj o innych podejściach do interakcji danych
Jimmy Hoffa

Odpowiedzi:

13

Cóż, możesz zobaczyć dobry przykład w Spring Data Framework, który jest oparty na koncepcji repozytoriów.

Tam zobaczysz, że repozytoria zajmują się tylko magazynem danych i rzadko zawierają logikę biznesową (jest to zarezerwowane dla warstwy usług). Na przykład, gdy spojrzysz na ich projekt, zobaczysz, że mają interfejs CRUDRepository , który udostępnia metody tworzenia, niszczenia i odzyskiwania jednostek (między innymi). Istnieje również PagingAndSortingRepository, który dodaje dodatkową funkcjonalność do tego, sortowania i stronicowania wyników itp.

Ramy te są więc prawdopodobnie dobrym miejscem do studiowania dobrego projektu repozytorium.

O ile mi wiadomo, wiele koncepcji wdrożonych przez Spring Data Framework pochodzi z doskonałej książki o nazwie Domain-Driven Design: Tackling Complexity in the Heart of Software , książka ta ma całą sekcję poświęconą projektowaniu repozytorium.

Możesz rozważyć jego kopię.

Mały fragment książki wyjaśnia:

Wzorzec REPOSITORY jest prostym szkieletem koncepcyjnym, który zawiera te rozwiązania i przywraca koncentrację na naszym modelu.

REPOZYTORIUM reprezentuje wszystkie obiekty określonego typu jako zbiór pojęciowy (zwykle emulowany). Działa jak kolekcja, z wyjątkiem bardziej skomplikowanych funkcji zapytań. Obiekty odpowiedniego typu są dodawane i usuwane, a mechanizm stojący za REPOSITORY wstawia je lub usuwa z bazy danych. Definicja ta zawiera spójny zestaw obowiązków za zapewnienie dostępu do korzeni AGREGATÓW od wczesnego cyklu życia do końca.

Klienci żądają obiektów z REPOSITORY przy użyciu metod zapytań, które wybierają obiekty na podstawie kryteriów określonych przez klienta, zwykle wartości niektórych atrybutów. REPOSITORY pobiera żądany obiekt, enkapsulując maszynerię zapytań do bazy danych i mapowania metadanych. REPOZYTORIE mogą zaimplementować różnorodne zapytania, które wybierają obiekty na podstawie dowolnych kryteriów wymaganych przez klienta. Mogą również zwrócić informacje podsumowujące, takie jak liczba wystąpień spełniających określone kryteria. Mogą nawet zwracać obliczenia podsumowujące, takie jak suma wszystkich pasujących obiektów jakiegoś atrybutu numerycznego.

REPOZYTORIUM odciąża klienta od ogromnych obciążeń, które mogą teraz rozmawiać z prostym interfejsem ujawniającym intencje i pytać o potrzeby w zakresie modelu. Do obsługi tego wszystkiego potrzeba dużo złożonej infrastruktury technicznej, ale interfejs jest prosty i koncepcyjnie połączony z modelem domeny.

W związku z tym:

Dla każdego typu obiektu, który wymaga globalnego dostępu, utwórz obiekt, który może zapewnić iluzję kolekcji w pamięci wszystkich obiektów tego typu. Skonfiguruj dostęp poprzez dobrze znany interfejs globalny.

Podaj metody dodawania i usuwania obiektów, które będą zawierały rzeczywiste wstawianie lub usuwanie danych w magazynie danych. Zapewnij metody, które wybierają obiekty na podstawie niektórych kryteriów i zwracają w pełni tworzone wystąpienia obiektów lub kolekcje obiektów, których wartości atrybutów spełniają kryteria, tym samym enkapsulując rzeczywistą technologię przechowywania i zapytań. Zapewniaj REPOZYTORIA tylko dla ZAGREGOWANYCH korzeni, które faktycznie potrzebują bezpośredniego dostępu. Skoncentruj klienta na modelu, delegując całą pamięć obiektów i dostęp do REPOZYTORIÓW.

edalorzo
źródło
4

Nie powinien zapewniać ani prostego interfejsu CRUD, ani logiki biznesowej. Pośredniczy między logiką biznesową a bazą danych. Interfejs powinien być logiczny, ale nie powinien wykonywać samej logiki biznesowej, bardziej jak prymitywna logika biznesowa. Przykładowo, masz zamiar zbudować system e-mail, masz użytkowników i wiadomości. Twoje repozytorium zapewniałoby podstawowe operacje CRUD dla użytkowników i wiadomości, ale zapewniałoby także filtrowane widoki wiadomości, takich jak GetUsersNewMessages (użytkownik) lub GetSearchedMessages (użytkownik, searchTerms).

Chodzi o to, że repozytorium ukrywa sposób implementacji pamięci i zapewnia przejrzysty interfejs, który umożliwia szybki elastyczny dostęp do danych. Utrzymywanie operacji na wysokim poziomie pod względem tego, co powinno się zdarzyć, a nie w jaki sposób oznacza to większą elastyczność we wdrażaniu ich w jakikolwiek sposób najlepszy dla bazowego sklepu z podkładami.

kamieniste
źródło