Gdzie w systemie MVC powinien znajdować się kod trwałości bazy danych?

21

Widziałem wiele konfiguracji utrwalania informacji w bazie danych. Zasadniczo w moim zakątku świata wydają się popularne trzy typy projektów:

  • Kontroler zarządza trwałością
  • Model zarządza trwałością
  • Biblioteka stron trzecich zarządza trwałością, zwykle wymagając pewnego rodzaju adnotacji w modelu.

Zastanawiam się, która konfiguracja (jeśli w ogóle) jest koncepcyjnie najłatwiejsza w użyciu / najbardziej kompatybilna z architekturą MVC?

(Jeśli nie wymieniłem go na liście, proszę podać krótki zarys / przegląd jako część odpowiedzi)

Blueberryfields
źródło

Odpowiedzi:

13

Druga i trzecia opcja są identyczne. M w MVC to nie model danych, ale raczej model domeny. Obejmuje to trwałość, wykonywaną bezpośrednio lub za pośrednictwem ORM, i obie są całkowicie poprawne.

Kontroler powinien zarządzać przepływem witryny i przekazywać rzeczy do domeny (czasami za pośrednictwem warstwy usług), które mają być obsługiwane, więc utrzymywanie się z nich jest złe - lub przynajmniej semantycznie niewygodne.

pdr
źródło
2
Nie zgadzam się do pewnego stopnia. Konkretne wykorzystanie trwałości jest logiką aplikacji, a zatem należy do warstwy aplikacji, a nie do warstwy domeny. Warstwa domeny (zawierająca model domeny) powinna być nieświadoma wytrwałości dla zwykłego programu biznesowego. Kontroler jest orkiestratorem . Może koordynować usługi (danych), interfejs użytkownika i model domeny.
Falcon
1
@ Falcon: Chociaż kontroler powinien kontrolować, kiedy dane są ładowane z bazy danych i utrwalane w bazie danych, nie ma problemu, aby kazała to zrobić modelowi. Użycie ORM (standard lub roll-your-own) zwykle oznacza przekazanie modelowi polecenia załadowania / zapisania, który następnie przekazuje go do ORM. Innym sposobem może być nakazanie kontrolerowi ORM załadowania / zapisania czegoś, przekazując mu klasę modelu do załadowania (z kryteriami wyboru) lub instancję modelu do zapisania. Tak czy inaczej, rzeczywiste ładowanie / zapisywanie będzie ściśle powiązane z modelem.
Marjan Venema
@Marjan Venema: Tak, zgadzam się, ale pytanie brzmi, gdzie powinien żyć ten kod. Staram się, aby model był jak najbardziej nieświadomy uporczywości i modeluję tylko podmioty domeny za pomocą ich zachowań i interakcji. Wszystko inne będzie istnieć w warstwach aplikacji (ponieważ jest to aplikacja mojego modelu). Dostęp do informacji / danych mapowania jest całkowicie oddzielony od modelu domeny i może również zająć się wersjonowaniem (uaktualnienie / obniżenie wersji). Zastosowanie dostępu do danych występuje również w warstwach aplikacji (które zawierają usługi, repozytoria itp.)
Falcon
@ Falcon: Tak, to dobry sposób na zrobienie tego i tak robiłem to w przeszłości, używając oddzielnych klas mapowania. Jednak wraz z pojawieniem się rozszerzonego RTTI (Delphi) i refleksji (.Net i inne), nie mam żadnych wątpliwości co do korzystania z nich w połączeniu z adnotacjami atrybutów Business Object Model, aby wszystko działało i wystarczyło użyć przeciążenia kodu, przechwytuje i / lub specjalnie zakodowane klasy inicjalizacji, aby zająć się wersjonowaniem bazy danych.
Marjan Venema
5

Realistycznie MVC to głównie wzór implementacji interfejsu użytkownika, więc pytanie jest nieco dyskusyjne. Są jednak tak naprawdę tylko dwie duże opcje. Kontroler zazwyczaj wysyła żądania załadowania lub zapisania encji w modelu za pomocą 1) jakiejś warstwy usługi lub 2) wzorca Active Record.

Warstwa usługi może przybierać dowolną liczbę form, choć osobiście wolę pracę z abstrakcją repozytorium dla agregowanych jednostek głównych, których konkretne implementacje będą działać z jakimś ORM, lekkim DAO lub API dla niektórych nierelacyjnych sklepów, jeśli ma to sens dla aplikacji.

Wzorzec Active Record oznacza, że ​​twój model jest odpowiedzialny za trwałość, chociaż zwykle oznacza to, że klasa podstawowa zarządza mapowaniami do twojego sklepu, więc twój model nie jest tak bezpośrednio zaangażowany.

Zasadniczo kontroler wysyła żądania utrwalania obiektów, niezależnie od tego, czy jest to wywołanie repozytorium, implementacja UnitOfWork, czy metoda Save na twoich jednostkach. Jeśli korzystasz z repozytoriów, obiekty modelu nie znają uporczywości.

JasonTrue
źródło
3

W systemie MVC (model-view-controller) model zawiera dane. Uważam więc, że trwałość bazy danych powinna w tym być.

Nettogrof
źródło
2

Większość próbek MVC wysokiego poziomu, które widziałem, ma osobną infrastructurewarstwę, która zawiera rzeczywisty kod implementacji bazy danych (tj. Konkretne wywołania do NHibernate, EF lub Linq lub cokolwiek, na czym polega twoja warstwa danych), podczas gdy warstwa „modelowa” (często również warstwa „Domena”) ma interfejsy, które definiują usługi danych.

Wayne Molina
źródło
0

Standardową praktyką w MVC jest uwzględnienie struktury danych i trwałości w warstwie M (odel).

Warstwa modelowa obejmuje nie tylko klasy (POCO itp.), Których będziesz używać w swojej aplikacji. Obejmują repozytoria tych klas.

Przykładem może być repozytorium, w którym znajdują się paczki instancji klas danych, tj .:

Clients repository

AllClients()
RecentClients()
ClientByID(int id)

Będziesz mógł lepiej zorganizować domenę modelu, a także mieć dostęp do swoich danych na wiele sposobów, ale warstwa danych / modelu będzie zwarta i solidna

Mihalis Bagos
źródło