An ORM is a kind of DAL, but not all DALs are ORMs

0

Próbuję się dowiedzieć czy poprawnie prowadzę komunikację ze swoją bazą danych, i wpadłem na taką odpowiedź na SO:
An ORM is a kind of DAL, but not all DALs are ORMs.

Zgodzicie się z tym? Jeśli tak, to mając skonfigurowany ORM, czy potrzebuję warstwy pośredniej między serwisem a kontekstem danych? Jest sens posiadania osobnej DAL, czy nie ma? I dlaczego?

Zgodnie z tym artykułem:

(repository) Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.

Skoro ORM już to wykonuje, to czy, i kiedy potrzebujemy DAL korzystając z ORM?

1

A warstwa logiki domenowej to będzie gdzie? Bo przecież nie w ORMowych klasach, bo te są związane ze strukturą bazy danych i nie ma to specjalnie sensu. Jak robisz CRUDa i logiki nie ma i tylko pchasz dane pomiędzy RESTem a SQLem to pewnie żadne repozytoria nie mają sensu. Ale jak robisz jakąś faktyczną aplikacje to nagle wygląda to trochę inaczej.

Trywialny przykład z życia wzięty: mam aplikacje która zarządza dostępem użytkowników do pewnych danych. Sama logika tam jest mocno złożona, ale jedno z wymagań jest takie, żeby admin mógł zrobić "override" dla wybranych danych dla wybranego użytkownika. Żeby to było trwałe to trzymamy sobie te override w bazie danych. Ale w samej logice domenowej aplikacji nie obchodzi mnie że np. user X ma 1000 takich override, szczególnie że dane mogłyby się tam zazębiać - interesuje mnie set te wszystkimi dostępnymi dla tego usera danymi, żeby można było szybko zrobić set intersection i wybrać dostępne pliki. Więc mimo że w bazie trzymamy te override per request (żeby można było np. któryś z nich usunąć), to wczytując to do aplikacji spłaszczamy to do mapy userId -> set<file>. Gdybym z jakiegoś powodu miał tam ORMa, to ORMowe klasy odzwierciedlałyby strukturę tabel i musiałbym i tak przerobić to na mój model domenowy z moją mapą.

Inny przykład też z życia wzięty: aplikacja dostaje requesty z listą plików. Taki request zapisujemy sobie trwale żeby nam gdzie nie uciekł po restarcie. Na podstawie plików z requestu robimy pewne operacje i dobieramy do tych plików także inne powiązane, wyciągamy też różne inne metadane w styli rozmiary, prawa dostępu itd. I to co user widzi w aplikacji na froncie to już ta "rozwinięta lista". Widać wyraźnie, ze to co trzymamy w bazie, a to co trzymamy w warstwie logiki domenowej to są dwie zupełnie różne rzeczy! I znów, jakbym miał tam ORMa to ten ORM mi najwyzej wczyta tą początkową listę, ale załadowanie faktycznego obiektu domenowego wymaga dużo więcej.

Zresztą co dopiero mówić o jakimś module raportowym który robi jakieś analityczne query na bazie. Jakby nie patrzeć jest to data access layer ale nijak sie ma do jakiegokolwiek mapowania relacji na obiekty ;)

6
bakunet napisał(a):

Zgodzicie się z tym? Jeśli tak, to mając skonfigurowany ORM, czy potrzebuję warstwy pośredniej między serwisem a kontekstem danych? Jest sens posiadania osobnej DAL, czy nie ma? I dlaczego?

Mam wrażenie, że nie rozumiałeś tego zdania. ORM jest jednym z rodzajów implementacji DAL. Są też inne: Table Data Gateway, Row Data Gateway, Active Record...

Zgodnie z tym artykułem:

(repository) Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.

Skoro ORM już to wykonuje, to czy, i kiedy potrzebujemy DAL korzystając z ORM?

ORM tego nie wykonuje. ORM operuje w sposób generyczny na źródle danych, ale nie wystawia specyficznego dla domeny interfejsu imitującego kolekcję obiektów domenowych.

Mając ORM masz DAL. A to, czy warto opakować ten DAL w repozytorium, to kwestia tego, czy masz domenę na tyle skomplikowaną, aby stosować DDD. Bez DDD Twoje repozytorium to tylko wrapper na ORMa, czyli nadal DAL.

0
Shalom napisał(a):

A warstwa logiki domenowej to będzie gdzie?

W jakiejś klasie serwisowej.

somekind napisał(a):

Mam wrażenie, że nie rozumiałeś tego zdania. ORM jest jednym z rodzajów implementacji DAL.

Tak też to zrozumiałem, ale chciałem się dowiedzieć jakie są jeszcze implementacje DAL i kiedy ORM nie wystarczy :) Dziękuję.

somekind napisał(a):

ORM tego nie wykonuje. ORM operuje w sposób generyczny na źródle danych, ale nie wystawia specyficznego dla domeny interfejsu imitującego kolekcję obiektów domenowych.

Wydawało mi się, że ORM to trochę taki właśnie mapper na źródło danych, Object–relational mapping. Choć nie do końca rozumiem drugiej części drugiego zdania:

nie wystawia specyficznego dla domeny interfejsu imitującego kolekcję obiektów domenowych.

2

Repozytorium to interface na granicy domeny i infrastruktury który ma w API obiekty domenowe, tj interface leży w domenie a implementacja w infrastrukturze. Obiekty/Encje domenowe to nie to samo co encja bazodanowa!
Google: Dependency Inversion Principle, Clean Architecture

2

Choć nie do końca rozumiem drugiej części drugiego zdania:

@bakunet przeczytaj te dwa przykłady które podałem. Myk polega na tym że model domenowy którym operujesz w aplikacji to nie jest to samo co model danych które trzymasz w bazie, chyba że piszesz CRUDa.

0

@Shalom: Ok, to powoli zaczyna nabierać dla mnie sensu. @somekind pisał o DDD przy bardziej skomplikowanym modelu domenowym.

Myk polega na tym, że mało widziałem i mało wiem. Poszukam na GH jakichś legitnych przykładów, bez tego to trochę jak uczyć się pływania z książki.

Dzięki.

0
bakunet napisał(a):

Tak też to zrozumiałem, ale chciałem się dowiedzieć jakie są jeszcze implementacje DAL i kiedy ORM nie wystarczy :) Dziękuję.

No jeśli potrzebna jest np. wysoka wydajność przy dostępie do jednej tabeli, to nie ma sensu do tego zaprzęgać ORMa, bo nic dobrego nie wniesie, więc można użyć wzorców, o których wspomniałem wcześniej.

Wydawało mi się, że ORM to trochę taki właśnie mapper na źródło danych, Object–relational mapping.

Tak, ORM to maper na źródło danych. Repozytorium to kolekcja obiektów biznesowych, a źródło danych jest szczegółem implementacji.

Choć nie do końca rozumiem drugiej części drugiego zdania:

nie wystawia specyficznego dla domeny interfejsu imitującego kolekcję obiektów domenowych.

ORM zazwyczaj przez jakiś swój obiekt daje Ci dostęp do metod crudowych: Find, List, GetById, Save, Update, Delete. Sensowne repozytorium wystawia rzeczy potrzebne domenie, czyli np. raczej bez List i Delete, za to z wyszukiwaniem na podstawie konkretnych kryteriów.

1 użytkowników online, w tym zalogowanych: 0, gości: 1