Z architektonicznego punktu widzenia, czy warstwa abstrakcji bazy danych, taka jak Microsoft Entity Framework, unieważnia potrzebę oddzielnej warstwy dostępu do danych?

11

Sposób w jaki było

Od lat organizuję swoje rozwiązania programowe jako takie:

  • Warstwa dostępu do danych (DAL) w celu wyodrębnienia działalności związanej z dostępem do danych
  • Warstwa logiki biznesowej (BLL) do stosowania reguł biznesowych do zestawów danych, obsługi uwierzytelniania itp.
  • Narzędzia (Util), które są po prostu biblioteką typowych metod narzędziowych, które zbudowałem w miarę upływu czasu.
  • Warstwa prezentacji, którą może być oczywiście przeglądarka internetowa, stacjonarna, mobilna, cokolwiek.

Tak jest teraz

Przez ostatnie cztery lata korzystałem z platformy Entity Framework firmy Microsoft (głównie jestem programistą .NET) i stwierdzam, że posiadanie DAL staje się bardziej kłopotliwe niż czyste ze względu na fakt, że Entity Framework już wykonał zadanie, które wykonywał mój DAL: to abstrakcja działalności polegającej na uruchamianiu CRUD w bazie danych.

Tak więc zazwyczaj kończę na DAL, który ma kolekcję metod takich jak ta:

public static IQueryable<SomeObject> GetObjects(){
    var db = new myDatabaseContext();
    return db.SomeObjectTable;
}

Następnie w BLL ta metoda jest używana jako taka:

public static List<SomeObject> GetMyObjects(int myId){
    return DAL.GetObjects.Where(ob => op.accountId == myId).ToList();
}

Jest to oczywiście prosty przykład, ponieważ BLL zwykle miałoby kilka dodatkowych linii logicznych, ale wydaje się to trochę przesadne, aby utrzymać DAL w tak ograniczonym zakresie.

Czy nie byłoby lepiej po prostu porzucić DAL i po prostu napisać moje metody BLL jako takie:

public static List<SomeObject> GetMyObjects(int myId){
    var db = new myDatabaseContext();
    return db.SomeObjectTable.Where(ob => op.accountId == myId).ToList();
}

Zastanawiam się nad usunięciem DAL z przyszłych projektów z wyżej wymienionych powodów, ale zanim to zrobiłem, chciałem sondować społeczność tutaj z perspektywy czasu / foresightu / opinii, zanim przejdę do projektu i odkryję problem, którego nie zrobiłem przewidywać.

Wszelkie myśli są mile widziane.

Aktualizacja

Wydaje się, że konsensus jest taki, że osobny DAL nie jest konieczny, ale (wyciągając własne wnioski tutaj) jest dobrym pomysłem, aby uniknąć blokady dostawcy. Na przykład, jeśli mam DAL, który wyodrębnia wywołania EF, jak pokazano powyżej, jeśli kiedykolwiek przechodzę na innego dostawcę, nie muszę przepisywać mojej BLL. Tylko te podstawowe zapytania w DAL będą musiały zostać przepisane. Powiedziawszy to, trudno mi sobie wyobrazić scenariusz, w którym to się stanie. Mogę już zrobić model EF bazy danych Oracle, MSSQL jest podany, jestem prawie pewien, że MySql jest również możliwy (??), więc nie jestem pewien, czy dodatkowy kod kiedykolwiek zapewniłby opłacalny zwrot z inwestycji.

Matt Cashatt
źródło
3
Czym różni się warstwa dostępu do danych od EF? Czy EF nie jest warstwą dostępu do danych? Jedyne powody, dla których widzę, aby zachować własną abstrakcję między logiką biznesową a EF, to ułatwienie testowania stubowania i uniknięcie zablokowania dostawcy.
Marjan Venema
2
Taki jest mój punkt widzenia - nie ma różnicy w moim spojrzeniu, ale szukam kontrapunktów. Dzięki.
Matt Cashatt
3
Osobiście nie widzę powodu, aby tworzyć osobny DAL, ponieważ EF / NHibernate to same w sobie warstwy dostępu do danych. Jak wspomniał Marjan, w EF można to rozważyć, jeśli widać zmianę dostawcy bazy danych, w NHibernate można zamienić sterowniki w jednym wierszu kodu (nawet sterownik SQLite do testowania w pamięci), więc byłby to niepotrzebny kod (IMO).
Patryk Ćwiek
3
Nie trzeba mieć dwóch DAL-ów. Jak powiedzieli inni, zachowaj BLL, ale uważaj, aby nie zablokować BLL w konstrukcjach specyficznych dla dostawcy. Zawsze lubię widzieć, jak wszystko sprowadza się do poziomu ciągu lub liczby całkowitej. Wiem wtedy, że mógłbym łatwo ujawnić całe złącze BLL / DAL w bardzo prymitywnym kanale, takim jak usługi sieciowe, port szeregowy, łącze telegraficzne, tylko żartowałem.
Andyz Smith
1
Ponowna aktualizacja: ta dodatkowa warstwa może znacznie ułatwić Unittests of busineslayer, ponieważ wyśmiewanie / karczowanie / fałszowanie GetMyObjects(int myId)jest łatwiejsze niż kpowanie / karczowanie / fałszowanie GetObjects.Where(ob => op.accountId == myId).ToList().
k3b

Odpowiedzi:

6

Nie jestem pewien, czy jest to odpowiedź, której szukasz ... ale proszę bardzo.

Robimy to, aby wszystko było podzielone / uporządkowane. Tak, EF / NHibernate mają dostęp do danych .. ale ograniczamy jego użycie do własnego zestawu z ogólną konfiguracją repozytorium. Ten zestaw zawiera również wszystkie nasze mapowania NHibernate, fabrykę sesji, kod do obsługi wielu baz danych itp.

Nadal nazywamy go „warstwą dostępu do danych”, ponieważ cały zespół istnieje w celu obsługi naszej ORM.

Powinienem chyba zauważyć, że nasza główna aplikacja odwołuje się do 5 baz danych, zawiera około 4-500 obiektów / mapowań domen i różnych schematów. Ta konfiguracja ma dla nas sens. Być może w przypadku mniejszej aplikacji pominiesz ten zestaw, ale .. jestem frajerem zorganizowanego kodu i prawdopodobnie i tak by to zrobił :)

Simon Whitehead
źródło
2

Widzę EF i DAL jako osobne komponenty w systemie Enterprise. Warstwa dostępu do danych jest abstrakcją używaną przez inne usługi do przechowywania danych i zarządzania nimi. Zazwyczaj Entity Framework buduje ładny interfejs API do tworzenia zapytań, aktualizowania, usuwania i wstawiania, jednak nadal wymagają bezpośredniego połączenia ze źródłem danych zaplecza. Tak więc każdy typ routingu lub zapory ogniowej zatrzyma działanie EF, co wymaga utworzenia komponentu mediacji EF.

Oto przykład wysokiego poziomu pokazujący, gdzie pasują DAL i EF:

-------------    -------                                    ----------------    ------
| Service A | -> | DAL | -> { LOCAL / LAN / WAN ACCESS } -> | DAL BACK-END | -> | EF |
-------------    -------                                    ----------------    ------

Z mojego doświadczenia wynika, że ​​lepszy projekt nigdy nie pozwala logice biznesowej ani implementacjom usług na bezpośredni dostęp do warstwy EF. Zamiast tego, aby zapewnić abstrakcję do pracy ze wszystkimi trwałymi danymi, która pozwala wysyłać żądania przez sieć lub wykonywać je lokalnie.

Ten projekt wprowadza jednak pewne nieszczelne abstrakcje. Dlatego należy to rozpatrywać indywidualnie dla każdego przypadku.

Kilka pytań, które należy zadać:

  • Czy wszystkie komponenty uzyskujące dostęp do danych będą mogły uzyskać połączenie ze składnicą danych zaplecza?
  • Czy Twój EF pozwala Ci agregować zestawy danych dla różnych typów magazynów danych? Na przykład za pomocą bazy danych SQL z MongoDB dla dokumentów.
Andrew T Finnell
źródło
1

W dzisiejszych czasach pytanie, czy zamierzasz zmienić przechowywanie danych, jest bardziej interesujące niż kiedyś, ponieważ pytanie może nie dotyczyć tylko zamiany MS SQL lub Oracle SQL, ale większe pytanie, czy może korzystać z różnych ofert przechowywania danych NoSQL jako repozytorium danych.

Jeśli istniała poważna możliwość takiej zmiany, warto pozostawić kod EF izolowany w DAL, abyś mógł wprowadzić nowy DAL w przyszłości, który zamapowałby twoje żądania repozytorium na bazę danych NoSQL. Może się tak zdarzyć, że taka zmiana i tak zakończy się hurtowym przepisaniem BLL z powodu założeń związanych z db, które pełzają oczywiście.

Podobnie EF w DAL prawdopodobnie uprościłby dostęp do danych w testach jednostek kodu BLL.

Uważam więc, że EF (lub inne ORMS) niekoniecznie unieważnia potrzebę warstwy dostępu do danych.

Alex White
źródło