Jaka jest różnica między wzorcem mapowania danych, bramą danych tabeli (bramą), obiektem dostępu do danych (DAO) i wzorcami repozytorium?

134

Próbuję odświeżyć swoje umiejętności projektowania wzorców i jestem ciekawy, jakie są różnice między tymi wzorami? Wszystkie wydają się być tym samym - hermetyzują logikę bazy danych dla określonej jednostki, aby kod wywołujący nie miał wiedzy o podstawowej warstwie trwałości. Z moich krótkich badań wynika, że ​​wszystkie z nich zazwyczaj wdrażają standardowe metody CRUD i usuwają szczegóły specyficzne dla bazy danych.

Oprócz konwencji nazewnictwa (np. CustomerMapper, CustomerDAO, CustomerGateway, CustomerRepository), jaka jest różnica? Jeśli jest różnica, kiedy wybrałbyś jedną z nich?

W przeszłości pisałbym kod podobny do poniższego (oczywiście uproszczony - normalnie nie używałbym właściwości publicznych):

public class Customer
{
    public long ID;
    public string FirstName;
    public string LastName;
    public string CompanyName;
}

public interface ICustomerGateway
{
    IList<Customer> GetAll();
    Customer GetCustomerByID(long id);
    bool AddNewCustomer(Customer customer);
    bool UpdateCustomer(Customer customer);
    bool DeleteCustomer(long id);
}

i mieć CustomerGatewayklasę, która implementuje określoną logikę bazy danych dla wszystkich metod. Czasami nie używałbym interfejsu i uczyniłbym wszystkie metody na CustomerGateway statycznymi (wiem, wiem, to sprawia, że ​​jest mniej testowalny), więc mogę to nazwać tak:

Customer cust = CustomerGateway.GetCustomerByID(42);

Wydaje się, że jest to ta sama zasada dla wzorców mapowania danych i repozytorium; wzorzec DAO (który jest tym samym co Gateway, jak sądzę?) również wydaje się zachęcać do tworzenia bram specyficznych dla bazy danych.

Czy coś mi brakuje? To wydaje się trochę dziwne, mieć 3-4 różne sposoby robienia dokładnie tego samego.

Wayne Molina
źródło

Odpowiedzi:

97

Twoje przykładowe warunki; DataMapper, DAO, DataTableGateway i Repository mają podobny cel (kiedy używam jednego, spodziewam się odzyskać obiekt klienta), ale inny cel / znaczenie i wynikająca z tego implementacja.

Repozytorium „działa jak zbiór, z wyjątkiem bardziej rozbudowanych możliwości wysyłania żądania” [ Evans Domain Driven Design ] i może być traktowane jako „obiekty w elewacji Memory” ( Repository dyskusja )

DataMapper „przenosi dane między obiektami i bazy danych, a jednocześnie zapewnić im niezależne od siebie i samego elementu odwzorowującego” ( Fowler, PoEAA, Mapper )

TableDataGateway jest „a Gateway (obiekt, który obudowuje dostęp do systemu zewnętrznego lub zasobów) do tabeli bazy danych. Jedna instancja uchwyty wszystkich wierszy w tabeli ” ( Fowler, PoEAA, TableDataGateway )

DAO „oddziela interfejs klienta Danych zasobu z jego mechanizmów dostępu do danych / adaptuje danych specyficznych dla danego zasobu dostępu API do rodzajowego interfejsu klienta” pozwalając „mechanizmy dostępu do danych, aby zmienić niezależnie od kodu, który wykorzystuje dane” ( Sun Plany )

Repozytorium wydaje się bardzo ogólne, nie ujawniając pojęcia interakcji z bazą danych. DAO zapewnia interfejs umożliwiający korzystanie z różnych podstawowych implementacji baz danych. TableDataGateway to w szczególności cienkie opakowanie wokół pojedynczego stołu. DataMapper działa jako pośrednik, umożliwiając obiektowi Model ewolucję niezależnie od reprezentacji bazy danych (w czasie).

Pierce Hickey
źródło
15
W rzeczywistości nie ma dużej różnicy między DAO i TableDataGateway iw [Fowler, PoEAA] [1] mówią dokładnie, że: „[Alur i in.] [2] omawia wzorzec Data Access Object, który jest Table Data Gateway. .. Użyłem innej nazwy, częściowo dlatego, że postrzegam ten wzorzec jako szczególne użycie bardziej ogólnej koncepcji Gateway (466) i chcę, aby nazwa wzorca to odzwierciedlała. " [1]: martinfowler.com/books/eaa.html [2]: books.google.pt/books/about/…
Miguel Gamboa
9
Słuszna uwaga. Mam wrażenie, że definicja TableDataGateway podana przez PoEAA jest węższa niż DataAccessObject. Wydaje się, że to pierwsze implikuje mapowanie jeden do jednego z (relacyjną) tabelą bazy danych, gdzie DAO może działać jako fasada dla wielu bazowych zasobów nierelacyjnych. W DAO nacisk kładzie się na możliwość zastąpienia bazowego magazynu danych, a nacisk w TableDataGateway na hermetyzację operacji SQL na pojedynczej tabeli (niekoniecznie w sposób neutralny / przenośny dla magazynu danych).
Pierce Hickey
32

W świecie projektowania oprogramowania istnieje tendencja (przynajmniej tak mi się wydaje) do wymyślania nowych nazw dla dobrze znanych starych rzeczy i wzorów. A kiedy mamy nowy paradygmat (który być może nieco różni się od już istniejących), zwykle zawiera on cały zestaw nowych nazw dla każdego poziomu. Tak więc „Logika biznesowa” staje się „warstwą usług” tylko dlatego, że mówimy, że robimy SOA, a DAO staje się repozytorium tylko dlatego, że mówimy, że robimy DDD (i żadna z nich nie jest w rzeczywistości czymś nowym i unikalnym, ale znowu: nowe nazwy dla znanych już koncepcji zebranych w tej samej książce). Więc nie mówię, że wszystkie te współczesne paradygmaty i akronimy oznaczają DOKŁADNIE to samo, ale naprawdę nie powinieneś być zbyt paranoikiem. W większości są to te same wzory, tylko z różnych rodzin.

Dmitry Perets
źródło
4
@MladenMihajlovic, tylko dlatego, że nie rozumiesz lub nie zgadzasz się, nie oznacza, że ​​ta odpowiedź jest nieprawidłowa lub zdarzenie jest poprawne.
Cypher
2
@MladenMihajlovic nie tak mówi ta odpowiedź. Ostatnie zdanie podsumowuje to.
Cypher,
2
@Cypher Czy te wzorce są w większości takie same? Nie oni nie są. Implementacja wzorca bramy różni się od implementacji wzorca repozytorium. Mogą wyglądać tak samo dla niewprawnego oka, ale tak nie jest. Ponadto, jak słusznie zauważył Mladen Mihajlovic, ta odpowiedź jest całkiem błędna. Logika biznesowa i warstwa usług to dwie różne rzeczy.
Frederik Krautwald
1
@Cypher To nie jest kwestia opinii, ale faktów. Wzorzec Gateway został sformułowany przez Martina Fowlera w jego PoEAA i jest on głównie powiązany z wzorami fasady lub adaptera [GoF]. Różnice polegają na tym, że bramka jest przeznaczona do określonego użytku i zwykle nie ma istniejącego interfejsu. Brama zwykle obejmuje tylko dwa obiekty, a opakowany zasób nie ma informacji o bramie. (kontynuuje ...)
Frederik Krautwald
3
To bardziej komentarz niż odpowiedź.
Pétur Ingi Egilsson
32

Data Mapper a Table Data Gateway Krótko mówiąc:

  • program Data Mapper otrzyma obiekt Domain Model (Entity) jako parametr i użyje go do zaimplementowania operacji CRUD
  • Table Data Gateway odbierze wszystkie parametry (jako prymitywy) dla metod i nie będzie wiedział nic o obiekcie Domain Model (Entity).

    W końcu oba będą działać jako mediator między obiektami w pamięci a bazą danych.

  • nascar
    źródło
    6
    link
    przestał działać
    1
    Zaktualizowany link: github.com/willdurand-edu/php-slides/blob/master/src/common/…
    Fernando Correia
    15

    Masz rację. Wybierz ten, który znasz najlepiej. Chciałbym zwrócić uwagę na kilka rzeczy, które mogą pomóc w wyjaśnieniu.

    Brama danych tabeli jest używana głównie w przypadku pojedynczej tabeli lub widoku. Zawiera wszystkie zaznaczenia, wstawienia, aktualizacje i usunięcia. Tak więc Klient to w Twoim przypadku stół lub widok. Tak więc jedno wystąpienie obiektu bramy danych tabeli obsługuje wszystkie wiersze tabeli. Zwykle jest to związane z jednym obiektem na tabelę bazy danych.

    Chociaż Data Mapper jest bardziej niezależny od dowolnej logiki domeny i jest mniej sprzężony (chociaż uważam, że istnieje sprzężenie lub brak sprzężenia). Jest to jedynie warstwa pośrednicząca, która przesyła dane między obiektami a bazą danych, zachowując ich niezależność od siebie nawzajem i samego programu odwzorowującego.

    Tak więc, zazwyczaj w programie mapującym, widzisz metody takie jak insert, update, delete, aw bramie danych tabeli znajdziesz getcustomerbyId, getcustomerbyName itp.

    Obiekt transferu danych różni się od powyższych dwóch wzorców, głównie dlatego, że jest wzorcem dystrybucji, a nie wzorcem źródła danych, jak powyższe dwa wzorce. Używaj go głównie, gdy pracujesz ze zdalnym interfejsem i chcesz, aby połączenia były mniej rozmowne, ponieważ każde połączenie może być drogie. Dlatego zwykle projektuje się DTO, które można serializować za pośrednictwem kabla, który może przenosić wszystkie dane z powrotem na serwer w celu zastosowania dalszych reguł biznesowych lub przetwarzania.

    Nie jestem dobrze zorientowany w wzorcu repozytorium, ponieważ do tej pory nie miałem okazji go użyć, ale będę szukał odpowiedzi innych.

    Srikar Doddi
    źródło
    1

    Poniżej znajduje się tylko moje zrozumienie.

    TableGateWay / RowDataGateWay : w tym kontekście Gateway odnosi się do konkretnej implementacji, w której każdy „obiekt domeny” ma odwzorowanie na każdą „bramę obiektu domeny”. Na przykład, jeśli mamy Person , będziemy mieć PersonGateway do przechowywania obiektu domeny Person w bazie danych. Jeśli mamy Osobę, Pracownika, Klienta itp., Będziemy mieć PersonGateway, EmployeeGateway i CustomerGateway. Każda brama będzie miała określoną funkcję CRUD dla tego obiektu i nie ma to nic wspólnego z inną bramą. Nie ma tutaj kodu / modułu wielokrotnego użytku. Bramkę można dalej podzielić na RowDataGateway lub TableGateway, w zależności od tego, czy przekażesz "id", czy "obiekt". Brama jest zwykle porównywana z rekordem aktywnym. Wiąże model domeny ze schematem bazy danych.

    Repozytorium / DataMapper / DAO : To to samo. Wszystkie odnoszą się do warstwy trwałości, która przenosi jednostki bazy danych do modelu domeny. W przeciwieństwie do bramy, Repozytorium / DataMapper / DAO ukrywa implementację. Nie wiesz, czy za osobą znajduje się brama PersonGateway. Może, ale nie musi, nie obchodzi cię. Wiesz tylko, że dla każdego obiektu domeny muszą być obsługiwane operacje CRUD. Oddziela źródło danych od modelu domeny.

    Hao Lu
    źródło