¿Por qué no necesitaría un ORM en un lenguaje funcional como Scala?


30

Me pregunto si puedo cambiar de Java a Scala en un proyecto Spring + Hibernate para aprovechar algunas características de Scala, como la coincidencia de patrones, la Opción y lo que me parece una sintaxis más limpia en general. He estado buscando el ORM por defecto en el ecosistema Scala y he encontrado que piensa como Activar (pero principalmente trato de encontrar si Hibernate se puede usar con Scala). Buscando esto, lo he leído en la documentación de Play sobre JPA + Scala.

Pero el punto más importante es: ¿realmente necesita un mapeador Relacional a Objetos cuando tiene el poder de un lenguaje funcional? Probablemente no. JPA es una forma conveniente de abstraer la falta de poder de Java en la transformación de datos, pero realmente se siente mal cuando comienza a usarlo desde Scala.

No tengo una comprensión profunda de cómo usar la programación funcional para crear una aplicación completa (es por eso que tengo la intención de usar Scala para poder entender esto gradualmente, ya que combina OO + Funcional), por lo que no puedo entender por qué no necesitaría un ORM con un lenguaje funcional y cuál sería el enfoque funcional para abordar la persistencia del modelo de dominio.

Un enfoque DDD para la lógica empresarial todavía tiene sentido con Scala, ¿no?


3
Esta es una pregunta basada en la opinión. Scala no es puramente funcional, también es un lenguaje OO, por lo que eso explicaría por qué aún querría usar una herramienta ORM. Para la asignación de bases de datos, consulte, por ejemplo: Slick , SORM , Anorm .
Jesper

No estoy buscando una opinión, estoy preguntando a algo con un profundo conocimiento del paradigma funcional cuál es la forma de lograr la persistencia. Sé que Scala es un híbrido y quiero usar su parte OO para DDD. ¿Entonces dice que si adopto un enfoque DDD incluso con Scala, un ORM es el camino a seguir?
gabrielgiussi

En lenguajes funcionales, se trata principalmente de valores que no tienen identidad como los objetos. Por lo tanto, no necesita el seguimiento de cambios, que es uno de los principales trabajos de un ORM.
Lee


55
No necesita un ORM en ningún idioma principal.
GrandmasterB

Respuestas:


30

Bueno, una cosa que es importante hacer cuando tenemos una discusión como esta es distinguir claramente entre mapeadores relacionales de objetos ("ORM") y las capas de abstracción de la base de datos . Un ORM es un tipo de capa de abstracción de base de datos, pero no todas las capas de abstracción de base de datos son ORM. Una buena herramienta para estudiar para comprender esto es la popular biblioteca SQLAlchemy de Python , que se autodenomina como un "kit de herramientas SQL y Object Relational Mapper" (mi negrita), con la idea de que estas son cosas diferentes. Como lo pusieron en su página de características clave :

No se requiere ORM

SQLAlchemy consta de dos componentes distintos, conocidos como Core y ORM . El Core es en sí mismo un conjunto de herramientas de abstracción SQL con todas las funciones, que proporciona una capa uniforme de abstracción sobre una amplia variedad de implementaciones y comportamientos de DBAPI, así como un lenguaje de expresión SQL que permite la expresión del lenguaje SQL a través de expresiones generativas de Python. Un sistema de representación de esquemas que puede emitir sentencias DDL, así como introspectar esquemas existentes, y un sistema de tipos que permite cualquier mapeo de tipos de Python a tipos de bases de datos, completa el sistema. El Object Relational Mapper es un paquete opcional que se basa en el Core.

La primera página describe el ORM de esta manera:

SQLAlchemy es famoso por su mapeador relacional de objetos (ORM), un componente opcional que proporciona el patrón del mapeador de datos, donde las clases se pueden mapear a la base de datos de forma abierta, de múltiples formas, permitiendo que el modelo de objetos y el esquema de la base de datos se desarrollen de una manera limpiamente desacoplado desde el principio.

La idea clave de un ORM es tratar de salvar el famoso desajuste de impedancia relacional de objetos . Esto significa definir las relaciones entre las clases definidas por el usuario con las tablas en un esquema de base de datos y proporcionar operaciones automáticas de "guardar" y "cargar" para las clases de su aplicación.

En contraste, las capas de abstracción de bases de datos que no son ORM tienden a estar más comprometidas con el modelo de datos relacionales y con SQL, y no con la orientación a objetos. Entonces, en lugar de presentar "asignaciones" entre tablas y clases y ocultar el esquema de la base de datos del programador, tienden a exponer la base de datos al programador pero con mejores API y abstracciones. Por ejemplo, los constructores de consultas SQL le permiten generar consultas SQL complejas mediante programación, sin manipulación de cadenas, como este ( un ejemplo de la biblioteca jOOQ para 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();

Ahora, el marco de Play no parece estar 100% en línea con lo que acabo de describir , pero su argumento parece estar en este espacio general: trabaje con el modelo relacional directamente en lugar de traducirlo a clases y viceversa.

La biblioteca jOOQ es digno de estudio como contrapunto a ORM. También tienen algunas entradas de blog relevantes que vale la pena leer:


19

Es un poco difícil de explicar hasta que hayas realizado mucha programación funcional. En la programación orientada a objetos, sus datos están atascados en un objeto y permanecen allí. Ese objeto se pasa un poco y se modifica bastante, pero generalmente se trabaja fundamentalmente con la misma "identidad" durante la vida útil de esos datos.

Los ORM generalmente están diseñados en torno a ese paradigma. Recupera algunos datos de la base de datos, los transforma en un objeto, posiblemente los modifica un montón, y cuando haya terminado, todavía tiene el mismo objeto que puede volver a escribir en la base de datos.

La programación funcional funciona de manera diferente. Sus datos no mantienen una identidad única durante su vida útil. Se divide, copia, comparte y transforma. De alguna manera fluye a través de un montón de funciones, luego eventualmente se vuelve a ensamblar en el formulario de salida que necesita. Para que cualquier API de base de datos se sienta natural en un lenguaje funcional, tiene que tener eso en cuenta, y JPA no.


1
+1000 Las personas que insisten en usar Scala como si fuera Java ++ me dan miedo por el futuro del lenguaje :(
Andres F.

9

En scala todavía es útil mapear tablas de bases de datos a objetos, y hay varias formas de hacerlo.

Un marco popular en el mundo de Scala es elegante . No es un ORM, porque hace menos (es decir, no busca relaciones sin que se le diga que haga uniones explícitamente).

Por lo tanto, todavía asigna objetos a las filas de la base de datos, pero sus objetos son inmutables (por lo tanto, no se elimina el estado) y ejecuta consultas explícitamente utilizando un DSL monádico. El resultado es que obtienes muchas de las partes "buenas" de un ORM sin los problemas relacionados con la mutabilidad y los problemas impredecibles de N + 1.

Se debe tener en cuenta que las personas han tenido un gran éxito al usar bibliotecas mucho más delgadas, como anorm o JDBC directo, también, utilizando técnicas funcionales para mantener el código hermoso.

Una biblioteca fantástica que aplica técnicas funcionales sobre JDBC también es doobie .

Por lo tanto, tiene muchas opciones para acceder a la base de datos, pero Hibernate (que parece ser el ORM de facto) no es una de las mejores, debido a que está sesgado hacia la mutabilidad.


0

No necesita un ORM incluso en lenguajes orientados a objetos.

Primero, ¿quién dijo que sus datos deberían copiarse físicamente de su almacenamiento persistente a su objeto? Alan Kay , un hombre detrás de Smalltalk, quería objetos para deshacerse de los datos . Sugirió que un objeto solo puede tener una referencia a alguna área donde se almacenan sus datos.

Segundo, ¿cuál es la mejor manera de lograrlo? Recomiendo identificar sus objetos por sus responsabilidades , y no pensar en los datos que poseen. Si has oído hablar del enfoque de las tarjetas CRC, se usa exactamente para eso.

Y, finalmente, en caso de que alguna vez regrese al campo OO, aquí hay una forma de implementarlo .

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.