Perché non avrei bisogno di un ORM in un linguaggio funzionale come Scala?


30

Mi chiedo se posso passare da Java a Scala in un progetto Spring + Hibernate per sfruttare alcune funzionalità di Scala come pattern matching, Option e quella che mi sembra una sintassi più pulita in generale. Ho cercato l'ORM per impostazione predefinita nell'ecosistema Scala e ho trovato pensieri come Activate (ma soprattutto cerco di scoprire se Hibernate può essere usato con Scala). Cercando questo ho letto questo nella documentazione di Play su JPA + Scala.

Ma il punto più importante è: hai davvero bisogno di un mappatore relazionale agli oggetti quando hai la potenza di un linguaggio funzionale? Probabilmente no. JPA è un modo conveniente per astrarre la mancanza di potere di Java nella trasformazione dei dati, ma sembra davvero sbagliato quando inizi a usarlo da Scala.

Non ho una profonda conoscenza di come utilizzare la programmazione funzionale per creare un'applicazione completa (ecco perché intendo utilizzare Scala in modo da poterlo comprendere in modo incrementale, poiché combina OO + funzionale), quindi non riesco a capire perché non avrei bisogno di un ORM con un linguaggio funzionale e quale sarebbe l'approccio funzionale per affrontare la persistenza del modello di dominio.

Un approccio DDD per la logica aziendale ha ancora senso con Scala, non è vero?


3
Questa è una domanda basata sull'opinione. Scala non è puramente funzionale, è anche un linguaggio OO, quindi ciò spiegherebbe perché vorresti ancora usare uno strumento ORM. Per il mapping dei DB, vedere ad esempio: Slick , SORM , Anorm .
Jesper,

Non sto cercando un'opinione, sto chiedendo a qualcosa con una profonda comprensione del paradigma funzionale qual è il modo per raggiungere la persistenza. So che Scala è un ibrido e voglio usare la sua parte OO per DDD. Quindi dici che se seguo un approccio DDD anche con Scala, un ORM è la strada da percorrere?
gabrielgiussi,

Nei linguaggi funzionali ti occupi principalmente di valori che non hanno identità come fanno gli oggetti. Pertanto non è necessario il rilevamento delle modifiche, che è uno dei principali lavori di un ORM.
Lee,

2

5
Non hai bisogno di un ORM in nessuna delle principali lingue.
GrandmasterB,

Risposte:


30

Bene, una cosa che è importante fare ogni volta che abbiamo una discussione come questa è di distinguere chiaramente tra mappatori relazionali di oggetti ("ORM") e livelli di astrazione del database . Un ORM è un tipo di livello di astrazione del database, ma non tutti i livelli di astrazione del database sono ORM. Un buon strumento per studiare per capire questo è la popolare libreria SQLAlchemy di Python , che si autodefinisce come "toolkit SQL e Object Relational Mapper" (il mio grassetto), con l'idea che si tratta di cose diverse. Come lo inseriscono nella pagina delle caratteristiche principali :

Nessun ORM richiesto

SQLAlchemy è costituito da due componenti distinti, noti come Core e ORM . Il Core è esso stesso un toolkit di astrazione SQL con funzionalità complete, che fornisce un livello uniforme di astrazione su un'ampia varietà di implementazioni e comportamenti DBAPI, nonché un linguaggio di espressioni SQL che consente l'espressione del linguaggio SQL tramite espressioni generative di Python. Un sistema di rappresentazione dello schema che può sia emettere istruzioni DDL che schemi esistenti introspetti e un sistema di tipi che consente qualsiasi mapping dei tipi Python ai tipi di database, completa il sistema. Object Relational Mapper è quindi un pacchetto opzionale che si basa sul Core.

La prima pagina descrive l'ORM in questo modo:

SQLAlchemy è famoso soprattutto per il suo ORM (object-relational mapper), un componente opzionale che fornisce il modello di mappatore di dati, in cui le classi possono essere mappate al database in modo aperto, in diversi modi - consentendo al modello a oggetti e allo schema del database di svilupparsi in un modo chiaramente disaccoppiato dall'inizio.

L'idea chiave di un ORM è quella di provare a colmare il famoso disadattamento dell'impedenza relazionale oggetto . Ciò significa definire relazioni tra classi definite dall'utente e tabelle in uno schema di database e fornire operazioni di "salvataggio" e "caricamento" automatiche per le classi dell'applicazione.

Al contrario, i livelli di astrazione di database non ORM tendono a impegnarsi maggiormente nel modello di dati relazionali e in SQL e non nell'orientamento agli oggetti. Quindi, invece di presentare "mappature" tra tabelle e classi e nascondere lo schema del database al programmatore, tendono ad esporre il database al programmatore ma con API e astrazioni migliori. Ad esempio, i compilatori di query SQL consentono di generare query SQL complesse a livello di codice , senza manipolazione di stringhe, come questa ( un esempio dalla libreria jOOQ per 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();

Ora, il framework Play non sembra essere al 100% in combutta con quello che ho appena descritto , ma il loro argomento sembra essere in questo spazio generale: lavorare direttamente con il modello relazionale invece di tradurlo in classi e tornare da loro.

La biblioteca jOOQ vale la pena studiare come contrappunto alla ORM. Hanno anche alcuni post di blog pertinenti che vale la pena leggere:


19

È difficile da spiegare fino a quando non hai fatto molta programmazione funzionale. Nella programmazione orientata agli oggetti, i tuoi dati sono in qualche modo bloccati in un oggetto e rimangono lì. Quell'oggetto viene passato un po 'in giro e modificato un po', ma di solito stai fondamentalmente lavorando con la stessa "identità" per tutta la durata di quei dati.

Gli ORM sono generalmente progettati attorno a quel paradigma. Recuperi alcuni dati dal database, li immergi in un oggetto, potenzialmente li modifichi un gruppo e quando hai finito, hai ancora lo stesso oggetto che puoi riscrivere nel database.

La programmazione funzionale funziona in modo diverso. I tuoi dati non mantengono un'unica identità per tutta la sua vita. Viene suddiviso, copiato, condiviso e trasformato. In un certo senso scorre attraverso un mucchio di funzioni, quindi alla fine viene riassemblato nella forma di output di cui hai bisogno. Affinché qualsiasi API del database si senta naturale in un linguaggio funzionale, deve tenerne conto e JPA no.


1
+1000 Le persone che insistono nell'usare Scala come se fosse Java ++ mi fanno paura per il futuro della lingua :(
Andres F.

9

In scala è ancora utile mappare le tabelle del database sugli oggetti e ci sono diversi modi per farlo.

Un quadro popolare nel mondo di Scala è slick . Non è un ORM, perché fa di meno (vale a dire, non recupera le relazioni senza che gli venga detto di fare unioni esplicite).

Quindi si mappano ancora gli oggetti alle righe del database, ma i propri oggetti sono immutabili (quindi senza alcun flush dello stato) e si eseguono esplicitamente query utilizzando un DSL monadico. Il risultato è che ottieni molte delle parti "buone" di un ORM senza i problemi di mutabilità e imprevedibili problemi di N + 1.

Va notato che le persone hanno ottenuto un grande successo usando librerie molto più sottili, come anorm o JDBC, usando tecniche funzionali per mantenere il codice bello.

Una fantastica libreria che applica tecniche funzionali su JDBC è anche Doobie .

Quindi hai molte scelte per l'accesso al database, ma Hibernate (che sembra essere l'ORM di fatto) non è uno dei migliori, a causa della sua propensione alla mutabilità.


0

Non è necessario un ORM nemmeno nei linguaggi orientati agli oggetti.

Primo, chi ha detto che i tuoi dati dovrebbero essere fisicamente copiati dalla tua memoria persistente al tuo oggetto? Alan Kay , un uomo dietro Smalltalk, voleva che gli oggetti si sbarazzassero dei dati . Ha suggerito che un oggetto può avere solo un riferimento ad un'area in cui sono memorizzati i suoi dati.

Secondo: qual è il modo migliore per raggiungerlo? Consiglio di identificare i tuoi oggetti in base alle loro responsabilità e di non pensare ai dati in loro possesso. Se hai sentito parlare dell'approccio alle carte CRC, viene utilizzato esattamente per questo.

E, infine, nel caso in cui tornassi al campo OO, ecco un modo per implementarlo .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.