Jaki konkretny problem rozwiązuje wzór repozytorium?

(Uwaga: moje pytanie ma bardzo podobne obawy jak osoba, która zadała to pytanie trzy miesiące temu, ale nigdy nie została udzielona odpowiedź.)

Ostatnio zacząłem pracować z MVC3 + Entity Framework i czytałem, że najlepszą praktyką jest użycie wzorca repozytorium do scentralizowania dostępu do DAL. Towarzyszy temu również wyjaśnienie, że chcesz oddzielać DAL od domeny, a zwłaszcza warstwy widoku. Ale w przykładach widziałem repozytorium jest (lub wydaje się być) po prostu zwracając encje DAL, tzn. w moim przypadku repozytorium zwróciłoby encje EF.

Więc moje pytanie brzmi, co dobre jest repozytorium, jeśli zwraca tylko encje DAL? Czy to nie dodaje warstwy złożoności, która nie eliminuje problemu przenoszenia jednostek DAL między warstwami? Jeśli wzorzec repozytorium tworzy "pojedynczy punkt wejścia do DAL", czym to się różni od obiektu context? Jeżeli repozytorium dostarcza mechanizm odzyskiwania i utrzymywania obiektów DAL, czym to się różni od obiektu context?

Czytałem też w co najmniej jednym miejscu, że Unit of Work pattern centralizuje dostęp do repozytorium w celu zarządzania obiektami kontekstu danych, ale nie wiem też, dlaczego jest to ważne.

Jestem na 98,8% pewien, że coś tu przeoczyłem, ale z moich odczytów tego nie zauważyłem. Oczywiście, że nie czytam odpowiednich źródeł... :\

Author: Community, 2012-11-01

7 answers

Entity Framework DbContext zasadniczo przypomina repozytorium (oraz jednostka pracy ). Nie musisz tego streszczać w prostych scenariuszach.

Główną zaletą repozytorium jest to, że Twoja domena może być ignorowana i niezależna od mechanizmu persistence. W architekturze opartej na warstwach zależności wskazują od warstwy interfejsu użytkownika w dół Przez domenę (lub Zwykle nazywaną warstwą logiki biznesowej) do warstwy dostępu do danych. Oznacza to interfejs użytkownika zależy od BLL, który sam zależy od DAL.

W bardziej nowoczesnej architekturze (propagowanej przez domain-driven design i inne podejścia obiektowe) domena nie powinna mieć zależności skierowanych na zewnątrz. Oznacza to, że interfejs użytkownika, mechanizm trwałości i wszystko inne powinny zależeć od domeny, a nie na odwrót.

Repozytorium będzie następnie reprezentowane przez jego interfejs wewnątrz domeny, ale ma swoją konkretną implementację poza domeną, w module trwałość. W ten sposób domena zależy tylko od abstrakcyjnego interfejsu, a nie konkretnej implementacji.

To w zasadzie orientacja obiektowa a programowanie proceduralne na poziomie architektonicznym.

Zobacz też porty i Adaptery vel Architektura heksagonalna.

Kolejną zaletą repozytorium jest możliwość tworzenia podobnych mechanizmów dostępu do różnych źródeł danych. Nie tylko do baz danych, ale do chmury sklepy, zewnętrzne interfejsy API, aplikacje innych firm itp.

 20
Author: Dennis Traub,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-01 16:03:15

Myślę, że termin "repozytorium" jest powszechnie uważany za sposób " repository pattern" jest opisany w książce Patterns of Enterprise Application Architecture autorstwa Martina Fowlera.

Repozytorium pośredniczy między warstwami mapowania domeny i danych, działa jak kolekcja obiektów domeny w pamięci. Obiekty klienta konstruować deklaratywnie specyfikacje zapytań i przesyłać je do Repozytorium dla zadowolenia. Obiekty mogą być dodawane i usuwane od repozytorium, jak mogą z prostego zbioru obiektów, a kod mapujący zamknięty przez repozytorium przeprowadzi odpowiednie operacje za kulisami.

Na pozór, Entity Framework realizuje to wszystko i może być używany jako prosta forma repozytorium. Jednak w repozytorium może być więcej niż tylko abstrakcja warstwy danych.

Zgodnie z książką Domain Driven Design autorstwa Erica Evansa, repozytorium ma zalety:

  • prezentują klientom prosty model uzyskiwania obiektów trwałości i zarządzania ich cyklem życia [19]} [18]} oddzielają projektowanie aplikacji i domen od technologii trwałości, wielu strategii baz danych, a nawet wielu źródeł danych [19]}
  • komunikują decyzje projektowe o dostępie do obiektu
  • [18]}pozwalają na łatwe zastąpienie atrapy implementacji, do testów jednostkowych (zazwyczaj przy użyciu pamięci kolekcja).

Pierwszy punkt z grubsza odpowiada powyższemu akapitowi i łatwo zauważyć, że sam Entity Framework łatwo go realizuje.

Niektórzy twierdzą, że EF realizuje również drugi punkt. Ale zwykle EF jest używany po prostu, aby przekształcić każdą tabelę bazy danych w encję EF i przekazać ją do interfejsu użytkownika. Może to być abstrakcja mechanizmu dostępu do danych, ale nie jest to abstrakcja relacyjnej struktury danych za kulisami.

W prostszych aplikacjach, które głównie zorientowane na dane , może to nie wydawać się ważnym punktem. Ale ponieważ reguły domeny aplikacji / logika biznesowa stają się bardziej złożone, możesz chcieć być bardziej zorientowany obiektowo. Często zdarza się, że struktura relacyjna danych zawiera idiosynkrazje, które nie są ważne dla domeny biznesowej, ale są efektami ubocznymi przechowywania danych. W takich przypadkach nie wystarczy abstrakcja mechanizmu trwałości, ale również charakter samej struktury danych. Sam EF na ogół nie pomoże Ci w tym, ale zrobi to warstwa repozytorium.

Jeśli chodzi o trzecią przewagę, EF nie zrobi nic (z perspektywy DDD), aby pomóc. Zazwyczaj DDD używa repozytorium nie tylko do abstrakcji mechanizmu trwałości danych, ale także do zapewnienia ograniczeń dotyczących dostępu do określonych danych:

Nie potrzebujemy również dostępu do zapytań dla trwałych obiektów, które są bardziej wygodne do znalezienia przez Trawers. Na przykład, adres osoby może być wymagane od osoby obiektu. I najważniejsze, wszelkie obiekt wewnętrzny do agregatu jest zabroniony, z wyjątkiem Trawers z korzenia.

Innymi słowy, nie masz 'AddressRepository' tylko dlatego, że masz tabelę adresów w bazie danych. Jeśli projekt zdecyduje się zarządzać sposobem dostępu do obiektów adresowych w ten sposób, PersonRepository jest miejscem, w którym można zdefiniować i wymusić projekt wybór.

Również repozytorium DDD zazwyczaj zawiera pewne koncepcje biznesowe związane z zestawami danych domenowych. OrderRepository może mieć metodę o nazwie OutstandingOrdersForAccount, która zwraca określony podzbiór zamówień. Repozytorium Klienta może też zawierać metodę PreferredCustomerByPostalCode.

Klasy DataContext Entity Framework nie nadają się dobrze do takiej funkcjonalności bez dodatkowej warstwy abstrakcji repozytorium. Pracują dobrze dla tego, co DDD wywołuje specyfikacje, które mogą być proste wyrażenia logiczne wysyłane do prostej metody, która oceni dane względem wyrażenia i zwróci dopasowanie.

Jeśli chodzi o czwartą zaletę, chociaż jestem pewien, że istnieją pewne strategie, które mogą pozwolić na zastąpienie datacontext, owinięcie go w repozytorium czyni go martwym prostym.

Jeśli chodzi o "jednostkę pracy", oto co ma do powiedzenia książka DDD:

pozostaw kontrolę transakcji do klient. chociaż repozytorium będzie wstawiać i usuwać z bazy danych, zwykle nie będzie popełnić cokolwiek. Kuszące jest commit po zapisaniu, na przykład, ale klient prawdopodobnie ma kontekst, aby poprawnie zainicjować i Zatwierdź jednostki pracy. Zarządzanie transakcjami będzie prostsze, jeśli Repozytorium trzyma ręce z dala.

 47
Author: Eric King,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-02 15:30:07

Masz rację, w tych prostych przypadkach repozytorium jest tylko kolejną nazwą DAO i przynosi tylko jedną wartość: fakt, że można przełączyć EF na inną technikę dostępu do danych. Dziś używasz MSSQL, jutro będziesz chciał przechowywania w chmurze. Lub używając micro orm zamiast EF lub przełączając się z MSSQL na MySql.

We wszystkich tych przypadkach dobrze jest, że używasz repozytorium, ponieważ reszta aplikacji nie będzie dbać o to, jakiego magazynu używasz teraz.

Jest też sprawa limitowana tam, gdzie otrzymujesz informacje z wielu źródeł (db + system plików), repo będzie działać jako fasada, ale nadal jest to inna nazwa dla DAO.

Repozytorium "prawdziwe" jest ważne tylko wtedy, gdy masz do czynienia z obiektami domenowymi/biznesowymi, dla aplikacji skoncentrowanych na danych, które nie zmieniają pamięci masowej, wystarczy sam ORM.

 6
Author: MikeSW,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-01 15:56:32

Byłoby to przydatne w sytuacjach, gdy masz wiele źródeł danych i chcesz uzyskać do nich dostęp przy użyciu spójnej strategii kodowania.

Na przykład możesz mieć wiele modeli danych EF i niektóre dane dostępne za pomocą tradycyjnego ADO.NET z przechowywanymi procami i niektórymi danymi dostępnymi za pomocą interfejsu API innych firm, a niektórymi dostępnymi z bazy danych Access żyjącej na serwerze Windows NT4, siedzącej pod kocem kurzu w szafie na miotły.

Możesz nie chcieć swojej firmy lub front-endu warstwy, aby dbać o to, skąd pochodzą dane, więc budujesz ogólny wzorzec repozytorium, aby uzyskać dostęp do "danych", a nie do"danych struktury jednostki".

W tym scenariuszu, rzeczywiste implementacje repozytorium będą się różnić od siebie, ale kod, który je wywołuje, nie będzie wiedział różnicy.

 2
Author: Joe Enos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-01 15:52:43

Biorąc pod uwagę twój scenariusz, po prostu zdecydowałbym się na zestaw interfejsów, które reprezentują jakie struktury danych (modele domeny) muszą zostać zwrócone z Twojej warstwy danych. Twoja implementacja może być wtedy mieszaniną EF, Raw ADO.Net lub innego rodzaju przechowywania danych / dostawcy. Kluczową strategią jest tutaj to, że implementacja jest oderwana od bezpośredniego konsumenta-warstwy domeny. Jest to przydatne, gdy chcesz przetestować obiekty domeny i, w mniej powszechnych sytuacjach - zmienić Twój dostawca danych / platforma baz danych.

Powinieneś, jeśli jeszcze tego nie zrobiłeś, rozważyć użycie kontenera IOC , ponieważ ułatwiają one luźne łączenie twojego roztworu za pomocą Dependency Injection. jest wiele dostępnych , osobiście wolę Ninject .

Warstwa domeny powinna zawierać całą twoją logikę biznesową - reguły i wymagania domeny problemowej, a może być wykorzystana bezpośrednio przez Twoją sieć MVC3 podanie. W pewnych sytuacjach warto wprowadzić warstwę usług , która znajduje się nad warstwą domeny, ale nie zawsze jest to konieczne i może być przesadą dla prostych aplikacji internetowych.

 2
Author: Baldy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-01 16:38:01

Kolejną rzeczą do rozważenia jest to, że nawet jeśli wiesz, że będziesz pracować z pojedynczym magazynem danych, nadal może mieć sens tworzenie abstrakcji repozytorium. Powodem jest to, że nie może być Funkcja, że aplikacja potrzebuje, że ORM du jour albo źle (wydajność), w ogóle, lub po prostu nie wiesz, jak zrobić ORM zginać do swoich potrzeb.

Jeśli owijasz swój ORM za dobrze przemyślany interfejs repozytorium, możesz łatwo przełączać się między różne technologie według własnego uznania. Nieczęsto w moich repozytoriach widzę, że niektóre metody wykorzystują EF do swojej pracy, a inne używają czegoś takiego jak PetaPoco, lub (gasp) ADO.net kod. Abstrakcja repozytorium umożliwia użycie dokładnie odpowiedniego narzędzia do danego zadania bez wycieku tych zawiłości do kodu klienta.

 1
Author: cdaq,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-29 20:11:48

Myślę, że jest duże nieporozumienie tego, co wiele artykułów nazywa " repozytorium."I dlatego pojawiają się wątpliwości co do rzeczywistej wartości tych abstrakcji.

Moim zdaniem repozytorium w czystej postaci jest liczniejsze, podczas gdy ty i wiele artykułów mówimy o " usłudze dostępu do danych."

Pisałem o tym tutaj .

 0
Author: Michael Logutov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-07 05:34:18