Dlaczego nie potrzebuję ORM w funkcjonalnym języku, takim jak Scala?


30

Zastanawiam się, czy mogę przełączyć się z Javy na Scalę w projekcie Spring + Hibernate, aby skorzystać z niektórych funkcji Scali, takich jak dopasowanie wzorca, Option i co wydaje mi się ogólnie czystszą składnią. Domyślnie szukałem ORM w ekosystemie Scala i odkryłem, że myśli jak Aktywacja (ale głównie próbuję sprawdzić, czy Hibernacji można używać ze Scalą). Szukając tego, przeczytałem to w dokumentacji Play na temat JPA + Scala.

Ale najważniejsze jest to: czy naprawdę potrzebujesz mapera relacji do obiektów, gdy masz moc funkcjonalnego języka? Prawdopodobnie nie. JPA to wygodny sposób na wyodrębnienie braku mocy Javy w transformacji danych, ale naprawdę źle się czuje, gdy zaczniesz go używać ze Scali.

Nie mam głębokiego zrozumienia, jak używać programowania funkcjonalnego do tworzenia kompletnych aplikacji (dlatego zamierzam używać Scali, aby móc to zrozumieć stopniowo, ponieważ łączy OO + funkcjonalne), więc nie mogę zrozumieć dlaczego nie potrzebowałbym ORM z funkcjonalnym językiem i jakie byłoby funkcjonalne podejście do radzenia sobie z trwałością modelu domeny.

Podejście DDD do logiki biznesowej nadal ma sens w Scali, prawda?


3
To pytanie oparte na opiniach. Scala nie jest czysto funkcjonalna, jest to także język OO, więc to wyjaśnia, dlaczego nadal chcesz używać narzędzia ORM. Aby zapoznać się z mapowaniem DB, patrz na przykład: Slick , SORM , Anorm .
Jesper,

Nie szukam opinii, proszę o coś z głębokim zrozumieniem paradygmatu funkcjonalnego, jaki jest sposób na osiągnięcie wytrwałości. Wiem, że Scala jest hybrydą i chcę użyć jej części OO do DDD. Więc mówisz, że jeśli przyjmuję podejście DDD nawet ze Scalą, ORM jest właściwym rozwiązaniem?
gabrielgiussi

W językach funkcjonalnych masz do czynienia głównie z wartościami, które nie mają identyczności jak obiekty. Dlatego nie potrzebujesz śledzenia zmian, które jest jednym z głównych zadań ORM.
Lee,


5
Nie potrzebujesz ORM w żadnym większym języku.
GrandmasterB

Odpowiedzi:


30

Cóż, jedną rzeczą, którą należy zrobić, gdy mamy taką dyskusję, jest wyraźne rozróżnienie między obiektowymi obiektami mapującymi obiekty („ORM”) a warstwami abstrakcji bazy danych . ORM jest rodzajem warstwy abstrakcji bazy danych, ale nie wszystkie warstwy abstrakcji bazy danych są ORM. Jednym z dobrych narzędzi do nauki, aby to zrozumieć, jest popularna biblioteka SQLAlchemy Pythona , która wystawia rachunek jako „zestaw narzędzi SQL i obiektowy obiektowy mapator” (moja pogrubiona czcionka), z myślą, że są to różne rzeczy. Po umieszczeniu go na stronie z kluczowymi funkcjami :

Nie wymaga ORM

SQLAlchemy składa się z dwóch różnych składników, znanych jako Core i ORM . Sam rdzeń jest w pełni funkcjonalnym zestawem narzędzi do abstrakcji SQL, zapewniając gładką warstwę abstrakcji w szerokim zakresie implementacji i zachowań DBAPI, a także język SQL Expression Language, który umożliwia wyrażanie języka SQL za pomocą generatywnych wyrażeń Python. System reprezentacji schematu, który może zarówno emitować instrukcje DDL, jak i introspekcję istniejących schematów, oraz system typów, który umożliwia dowolne mapowanie typów Pythona na typy baz danych, stanowi dopełnienie systemu. Object Relational Mapper to opcjonalny pakiet oparty na rdzeniu.

Pierwsza strona opisuje ORM w następujący sposób:

SQLAlchemy jest najbardziej znany ze swojego mapowania obiektowo-relacyjnego (ORM), opcjonalnego komponentu zapewniającego wzorzec mapowania danych, w którym klasy mogą być mapowane do bazy danych w sposób otwarty, na wiele sposobów - umożliwiając rozwój modelu obiektowego i schematu bazy danych w czysto oddzielony sposób od samego początku.

Kluczową ideą ORM jest próba pokonania słynnego niedopasowania impedancji relacyjnej względem obiektu . Oznacza to zdefiniowanie zależności między klasami zdefiniowanymi przez użytkownika a tabelami w schemacie bazy danych oraz zapewnienie automatycznych operacji „zapisywania” i „ładowania” klas aplikacji.

Natomiast warstwy abstrakcji baz danych inne niż ORM są bardziej zaangażowane w relacyjny model danych i SQL, a wcale nie w orientację obiektową. Zamiast więc oferować „odwzorowania” między tabelami i klasami i ukrywać schemat bazy danych przed programistą, mają tendencję do wystawiania bazy danych programistom, ale z lepszymi interfejsami API i abstrakcjami. Na przykład konstruktory zapytań SQL umożliwiają programowe generowanie złożonych zapytań SQL, bez manipulacji ciągami, takich jak ten ( przykład z biblioteki jOOQ dla Java ):

// Typesafely execute the SQL statement directly with jOOQ
Result<Record3<String, String, String>> result =
    create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
          .from(BOOK)
          .join(AUTHOR)
          .on(BOOK.AUTHOR_ID.equal(AUTHOR.ID))
          .where(BOOK.PUBLISHED_IN.equal(1948))
          .fetch();

Teraz środowisko Play nie wydaje się być w 100% zgodne z tym, co właśnie opisałem , ale ich argument wydaje się być w tej ogólnej przestrzeni: praca z modelem relacyjnym bezpośrednio zamiast przekładania go na klasy iz powrotem.

Biblioteka jOOQ jest warte studiowania jako kontrapunkt do ORMs. Mają też kilka odpowiednich wpisów na blogu, które warto przeczytać:


19

Trudno to wyjaśnić, dopóki nie wykonasz dużo programowania funkcjonalnego. W programowaniu obiektowym dane utknęły w jednym obiekcie i tam pozostają. Ten obiekt jest nieco przekazywany i modyfikowany, ale zazwyczaj zasadniczo pracujesz z tą samą „tożsamością” przez cały okres życia tych danych.

ORM są ogólnie projektowane wokół tego paradygmatu. Pobierasz niektóre dane z bazy danych, przenosisz je do obiektu, potencjalnie modyfikujesz kilka, a kiedy skończysz, nadal masz ten sam obiekt, który możesz zapisać z powrotem do bazy danych.

Programowanie funkcjonalne działa inaczej. Twoje dane nie zachowują jednej tożsamości przez cały okres użytkowania. Dzieli się, kopiuje, udostępnia i przekształca. W pewnym sensie przepływa przez szereg funkcji, a następnie zostaje ponownie złożony w potrzebną formę wyjściową. Aby każdy interfejs API bazy danych wydawał się naturalny w języku funkcjonalnym, musi to wziąć pod uwagę, a JPA tego nie robi.


1
+1000 Ludzie, którzy nalegają na używanie Scali tak, jakby to był Java ++, obawiają się przyszłości języka :(
Andres F.

9

W scali nadal przydatne jest mapowanie tabel bazy danych na obiekty, a jest na to kilka sposobów.

Jednym z popularnych frameworków w świecie Scali jest zręczny . To nie jest ORM, ponieważ robi mniej (a mianowicie nie pobiera relacji bez wyraźnego polecenia łączenia).

Więc nadal odwzorowujesz obiekty na wiersze bazy danych, ale twoje obiekty są niezmienne (stąd brak opróżniania stanu) i jawnie wykonujesz zapytania za pomocą monadycznej DSL. W rezultacie otrzymujesz wiele „dobrych” części ORM bez problemów związanych ze zmiennością i nieprzewidywalnymi problemami N + 1.

Należy zauważyć, że ludzie odnieśli wielki sukces, używając znacznie cieńszych bibliotek, takich jak anorm lub prosty JDBC, wykorzystując funkcjonalne techniki, aby zachować piękny kod.

Jedną fantastyczną biblioteką, która stosuje techniki funkcjonalne na JDBC, jest również doobie .

Masz więc wiele opcji dostępu do bazy danych, ale Hibernacja (która wydaje się być de facto ORM) nie jest jedną z najlepszych, ponieważ jest tendencyjna do zmienności.


0

Nie potrzebujesz ORM nawet w językach zorientowanych obiektowo.

Po pierwsze, kto powiedział, że twoje dane powinny być fizycznie skopiowane z twojego trwałego miejsca przechowywania do twojego obiektu? Alan Kay , człowiek stojący za Smalltalk, chciał, aby obiekty pozbyły się danych . Zasugerował, że obiekt może mieć odniesienie tylko do pewnego obszaru, w którym przechowywane są jego dane.

Po drugie - jaki jest najlepszy sposób na osiągnięcie tego? Zalecam identyfikowanie obiektów według ich obowiązków i nie myślenie o posiadanych przez nich danych. Jeśli słyszałeś o zbliżaniu się do kart CRC, to właśnie do tego służy.

I na koniec, na wypadek, gdybyś kiedykolwiek powrócił do pola OO, oto sposób na jego wdrożenie .

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.