windows store

Windows store podstawy: wzorzec repository oraz UoW28 lutego 2017

Witaj w trzeciej części serii dotyczącej tworzenia aplikacji! W poprzednich częściach opowiadaliśmy o składni XAML i szablonach oraz atrybutach. Dziś zgłębimy temat wzorca repository oraz Unit of Work.

  • Wzorzec repozytorium

Każdy z nas spotyka się podczas pisania aplikacji z koniecznością przechowywania danych kontrahentów: ich adresów, zamówień, faktur, informacji dotyczących magazynów czy choćby kodów rabatowych. Dane te musimy przetwarzać i wyświetlać niemalże na każdym kroku działania naszej aplikacji, w czym pomocny staje się wzorzec repozytorium.

Jest to jeden z najpopularniejszych wzorców projektowych. Spotkał się z nim każdy programista, który w swojej karierze napisał choć jedną aplikację związaną z bazami danych. Niestety, nie każdy próbuje się zagłębić i zrozumieć, dlaczego stosuje się właśnie ten typ wzorca.

Weźmy za przykład MVC złożone tylko z repozytorium, znajdującego się pomiędzy kontrolerami a bazą danych  (u mnie dochodzi do tego DbContext Entity Framework). Dla naszego przykładu przyjmiemy, że nazywa się ono Repository i jest implementacją interfejsu IRespository, przechowującego proste obiekty Customer.

1

Podstawowe repozytorium, implementujące interfejs, mogłoby wyglądać mniej więcej w ten sposób:

2

Oczywiście w naszym interfejsie możemy umieścić mniej lub bardziej skomplikowane metody, ale nie zawsze jest to konieczne.

Jak wygląda implementacja tego interfejsu? Pokażę to na przykładowej metodzie, którą można implementować analogicznie w innych przypadkach.

3

Nasza metoda  zwraca pierwszy napotkany obiekt, który ma właściwość Id równą tej

podanej na wejściu. W przykładowym kontrolerze wywołanie wspomnianej metody wyglądałoby następująco:

4

Tak jak widać, jest to bardzo proste, a napisanie tego typu repozytoriów w testach wręcz banalne, tak jak i wstrzykiwanie ich w konstruktorze. Co jednak,  jeśli mamy w swoim projekcie mnóstwo przeróżnych encji, a niektóre kontrolery muszą korzystać z kilku różnych repozytoriów? Czy musimy sporządzić mnóstwo instancji repozytoriów? Czy dla każdego z nich powinniśmy stworzyć nowy kontekst i wysyłać duże ilości zapytań do bazy tylko po to, by pokazać jakiś wykres w statystykach? Tutaj z pomocą przychodzi UoW.

  • Unit of Work

Uporządkowanie dużej liczby repozytoriów jest raczej skutkiem ubocznym niż bezpośrednim celem Unit of Work. Rzeczywista rola tego wzorca to zebranie operacji na kilku repozytoriach i wysłanie ich w formie jednej transakcji do bazy danych. Jest to o wiele mniejsze obciążenie, a przy okazji sprawia, że wśród repozytoriów panuje odrobinę mniejszy bałagan.

Prosty interfejs UoW może wyglądać następująco:

5

Wzorzec UoW najpierw „zbiera” zadania, które chcemy wykonać na jego repozytoriach, a następnie składa całość w jedną transakcję i wysyła do bazy. Gdybym w swoim projekcie nie korzystał z Entity Framework to:

  •  Unit of Work musiałby zawierać trochę więcej kodu i pełnić większą rolę,
  •  byłby użyteczny.
  • UoW + Repository w Entity Framework

Jak wygląda stosowanie powyższych wzorców z Entity Framework? Jeśli nie chcemy w żaden sposób wzbogacić tego, co oferują nam DbContext (Unit of Work) i jego DbSet (Repozytorium), to jedyne co osiągniemy przy użyciu prostych implementacji, to ograniczona funkcjonalność otrzymana z EF out of the box.

Gdyby nie to, że chciałem działać z repozytoriami generycznymi, to zapewne odwoływałbym się bezpośrednio do DbContextu.

  • Podsumowanie

Zalety wprowadzenia repozytorium jako warstwy izolującej dostęp do danych:

  • uniezależnienie warstwy przetwarzania danych (logika biznesowa) od implementacji warstwy dostępu do danych – wraz ze zmieniającymi się technologiami można łatwo dostarczać nowych, wydajniejszych implementacji repository, używających zupełnie innych technologii dostępu do danych (niekoniecznie nawet relacyjnych baz danych!),
  • umożliwienie łatwego zastępowania implementacji repozytorium – testy jednostkowe warstw przyległych bez efektów ubocznych dzięki implementacjom typu fake/stub.

Wady wprowadzenia repozytorium:

  • dodatkowa warstwa w architekturze aplikacji,
  • kontrowersje wokół wzorcowego interfejsu, jaki powinno implementować repozytorium, jeżeli technologia ORM sama z siebie jest już „repository”, to dodatkowe opakowywanie repository w inne repository może być dyskusyjne.

Na tym kończymy naszą serię! A już wkrótce zbadamy kolejny temat ze świata programistycznych zakątków – śledźcie nas na bieżąco 😉

Napisz komentarz

Zobacz inne wpisy: