Wzorzec projektowy repozytorium. DSP16 – część 10

Postanowiłem użyć w moim projekcie wzorca projektorowego: repozytorium (ang. repository). Myślę, że stworzenie samemu repozytorium nie jest takie trudne. Krok po kroku przedstawię jak można samemu do tego dojść.

Posiadam tabelę w bazie danych o nazwie Player, która jest odzwierciedlona w kodzie tak:

Posiadam również klasę dzięki której mam dostęp do bazy danych: DbContext. Aby pobrać wszystkie rekordy z bazy danych z informacjami o graczach wystarczy, że napiszę:

Powiedzmy, że chcę napisać klasę, która będzie wykonywała potrzebne operacje pobierania rekordów z bazy danych i zwracała to co potrzebuję: czyli wszystkich graczy oraz wszystkich graczy w kolejności alfabetycznej.

Proste. Na potrzeby testowania stworzę do tej klasy interfejs.

Po chwili jednak przyszło mi do głowy, że potrzebowałbym też wyciągnąć z bazy danych dane z tabeli Venue, której odzwierciedlenie w kodzie wygląda tak:

I również w tym przypadku chciałbym używać klasy, która zwracałaby to co potrzebuję i jest związane z Venue: Wszystkie dostępne miejsca oraz miejsca posortowane po dacie tygodnia w której grany jest turniej.Nie przejmując się wiele postanowiłem nową funkcjonalność wrzucić do istniejącej już klasy:

Rozszerzę interfejs:

Żyć nie umierać! Ale niestety łamię zasadę SOLID: Zasadę Jednej Odpowiedzialności – klasa Repository ma za dużo obowiązków: zajmuje się jednocześnie Graczami oraz Miejscami. No to naprawmy to. Stworzę osobną klasę, która będzie zwracać potrzebne rzeczy związane z klasą Venue oraz osobną klasę która będzie obsługiwać klasę Player.

Jak pewnie zauważyłeś od razu zaimplementowałem odpowiednie interfejsy. No bo po co klasa ma implementować coś z czego nie będzie korzystać (Zasada Segregacji Interfejsów)?

Rzucają mi się tu w oczy jeszcze dwie rzeczy: obydwie klasy mają jedno pole: DbContext oraz z obydwie klasy mają metodę której zadaniem jest wyciągniecie wszystkich elementów danego typu z bazy danych. Rozwiązaniem na to jest dziedziczenie klasy generycznej. Rozwiązanie podaję na talerzu:

To teraz poprawmy klasy: VenueRepository oraz PlayerRepository, aby dziedziczyły po klasie Repository.

Jak widać teraz używam tylko metody GetAll(). Dzięki zastosowaniu klasy generycznej, metoda GetAll zwraca albo graczy albo miejsca. To zależy w której klasie wywołam tą metodę. Idźmy dalej… Aby móc mockować klasę Repository wypadałoby dodać interfejs do tej klasy:

Wróćmy do IPlayerRepository oraz IVenueRepository. Poprawmy te interfejsy, pozbądźmy się niepotrzebnych metod.

Z interfejsów usunąłem metody GetAllPlayers oraz GetAllVenues. One są zastąpione przez jedną generyczną: GetAll.

 

Tak widzę właśnie budowę repozytorium od początku. Jeżeli chcesz zobaczyć jak można stworzyć dobre repozytorium zapraszam do obejrzenia filmiku na youtubie (patrz niżej), który moim zdaniem wyjaśnia całe zagadnienie w bardzo przystępny i fajny sposób.

Repozytorium, Linki:

Film na YouTubie, który świetnie wyjaśnia Repository Pattern

Marcin Dembowski o repozytorium

CodingTV – czy warto stosować repozytorium

 

 

Powered by: Wordpress