MOTORES
DE PERSISTENCIA. VERSION PARA IMPRIMIR.
(Versión original en
art3-1.html)
Dr. Vicent-Ramon Palasí Lallana.
Gerente General de Aurum Solutions.
http://www.aurumsol.com
Agosto 2003
Es
generalmente sabido que una aplicación informática
consta de dos componentes principales que colaboran para
llevar a cabo la funcionalidad que el usuario desea. El primero
de estos componentes es la base de datos, que guarda la información
necesaria para operar la aplicación, en forma de datos
en disco. El segundo de estos componentes es el programa
propiamente dicho, que recupera esos datos de la base de
datos, realiza los cálculos necesarios y presenta
los resultados deseados al usuario.
Figura 1. Arquitectura de una
aplicación informática
Para
que estos dos componentes puedan funcionar juntos deben
poder comunicarse intercambiando datos, como se observa en
la figura 1. En otras palabras, deben ser compatibles.
Sin embargo,
durante los últimos treinta años la evolución
de estos dos componentes ha sido divergente, de forma que
cada vez se ha hecho más difícil que colaboren
en una misma aplicación.
Así, desde los años 70 a la actualidad, las
bases de datos utilizan un modelo teórico llamado “relacional”,
que se ha convertido en un estándar y que es utilizado
en la práctica totalidad de aplicaciones de software.
En
cambio, los programas han usado, desde los años
80, un modelo llamado “orientado a objetos”,
que difiere en mucho del modelo relacional y que se ha extendido
cada vez más. Es por ello que aparece un conflicto
a la hora de reunir estos dos componentes en una aplicación,
ya que cada uno responde a diferente modelo y forma de operar.
Cada componente maneja los datos con un formato diferente.
Metafóricamente,
podríamos
afirmar que el programa y la base de datos hablan idiomas
diferentes
y,
por lo tanto,
la comunicación entre ellos resulta difícil.
Este
artículo comienza con una descripción
de los dos modelos mencionados y de las diferencias que dificultan
su combinación en una sola aplicación. A continuación,
se exploran las diferentes soluciones a este problema y se
acaba concluyendo que la mejor manera de resolverlo es usando
un motor de persistencia. El artículo finaliza indicando
los nombres de los motores de persistencia más usados,
con el fin de que el lector pueda elegir el que más
se adapta a sus necesidades.
1.
MODELO ORIENTADO A OBJETOS.
El
modelo orientado a objetos es el modelo teórico
que usa la mayoría de los programas actuales. La programación
orientada a objetos hunde sus raíces en los años
sesenta (en los que aparecieron los primeros lenguajes de
este tipo, llamados “Simula I” y “Simula
67”, desarrollados en el Centro Noruego de Computación,
en Oslo). En los primeros 70, aparece “Smalltalk”,
un lenguaje fundamental en la historia de la orientación
a objetos.
Sin
embargo, no es hasta la segunda mitad de los años
80 cuando la orientación de objetos se generaliza,
convirtiéndose
en el estándar predominante en los años 90,
de la mano de lenguajes como C++ y Java. El triunfo de la
programación orientada a objetos ha sido impulsado
por la enorme difusión de otras tecnologías
(como la interfaz gráfica o las arquitecturas distribuidas)
que son más fáciles de implementar mediante
este tipo de desarrollo que mediante una programación
tradicional.
Hoy
en día, la práctica totalidad de los lenguajes
de programación que surgen son orientados a objetos
y esta tecnología se ha convertido en el
estándar actual de programación que, a su vez,
está generando nuevos desarrollos muy prometedores
para el futuro (como, por ejemplo, la programación
orientada a aspectos).
La
idea de la orientación a objetos es modelar los
programas de una forma parecida a cómo percibimos
la realidad. Para la mente humana, el universo está compuesto
por una serie de “objetos” (en el sentido más
amplio de la palabra, incluyendo seres vivos, ideas, etc.).
Cada objeto tiene unas características que lo diferencian
de los demás y, con cada objeto, se pueden realizar
unas acciones que son propias y específicas del mismo.
Así, por ejemplo, un determinado auto tiene unas
características (color rojo, caja de cambios automática,
diesel, etc.) y puede realizar unas determinadas acciones
(acelerar, frenar, etc.).
La
programación orientada a objetos intenta modelar
estos objetos reales con estructuras de programa, llamadas “objetos
de software” o, simplemente, “objetos”.
Cada uno de estos objetos de software, está compuesto
por una serie de características (llamadas “atributos”)
y una serie de acciones (llamadas “métodos”),
al igual que un objeto de la vida real. Una representación
gráfica de un objeto de software se muestra en la
figura 2.
Figura 2. Representación gráfica
de un objeto de software
La
forma de programar estos objetos de software es similar
a la
forma en la que se comportan los objetos en la realidad.
Así, por ejemplo, en la vida real un auto contiene
piezas. Análogamente, en el programa, un objeto
de software “Auto” contiene
objetos “Pieza”, como podemos observar en la
figura 3.
Figura 3. El objeto "Auto" incluye objetos "Pieza"
Es
importante remarcar que el modelo orientado a objetos es
un modelo
que incluye tanto la parte estática de
un objeto (los “atributos” del mismo, es decir,
sus características) como su parte dinámica
(los “métodos”, es decir, sus acciones).
Usando una terminología bien conocida en desarrollo,
incluye tanto los “datos” como los “procesos”.
En
resumen, la programación orientada a objetos se
basa en la realidad. Su mayor ventaja es que simplifica el
mantenimiento de los programas y hace posible programar y
mantener hasta los programas más enormes al dividirlos
en partes más pequeñas, es decir, en objetos.
Como consecuencia, produce reducciones de costos y mayor
calidad del código y se ha convertido en el estándar
actual de programación.
2.
MODELO RELACIONAL.
Muy
ajeno a la revolución que supuso la orientación
a objetos, el área de las bases de datos sigue fiel
a un modelo antiguo pero que ha probado su eficacia, el llamado “modelo
relacional”.
El
modelo relacional se basa en un artículo publicado
por E.F.Codd en 1970. Las primeras bases de datos relacionales
comerciales aparecen en la segunda mitad de los años
setenta. Desde entonces, el modelo relacional se convierte
en un estándar prácticamente universal para
el acceso a datos, dominando totalmente el área de las bases
de datos hasta la actualidad.
El
modelo relacional es muy diferente del modelo orientado
a objetos.
Por una parte, el modelo relacional sólo
se ocupa de la parte estática de la aplicación
(de los “datos”) y no de la parte dinámica
(“los procesos”). Usando el ejemplo anterior,
en el modelo relacional, sólo me interesan las características
del auto (su color, su tipo de caja de cambios, etc) y no
las acciones que puedo hacer con él (acelerar, frenar,
etc.) . Este énfasis en los datos es lógico
en un modelo cuyo objetivo es modelar la parte estática
de la aplicación, es decir, la base de datos.
Hay
otras diferencias entre los dos modelos. Por ejemplo, la
forma
en la que el modelo relacional trata los datos es
muy diferente a cómo lo hace el modelo orientado a
objetos. Mientras en este último, los datos
son modelados en forma de objetos, en el modelo relacional
son modelados como registros, los cuales son una serie de
datos pertenecientes a una misma entidad de la vida real.
Un registro difiere de un objeto en que sólo modela
datos y que éstos no tienen estructura. La representación
gráfica de un registro aparece en la figura 4.
Figura 4. Representación gráfica
de un registro de datos
Los registros
similares se agrupan en tablas. Podemos imaginarnos las tablas
como listados de datos parecidos a los listados de impresión
que hay en las empresas (de empleados, de facturas, etc.).
En esta comparación, cada registro
sería
una línea
del listado.
Usando
el ejemplo anterior, cada registro contendría
los datos de un determinado auto (color rojo, caja de cambios
automática, diesel, etc.) y las tablas no serían
más que listas de autos con todos sus datos, como se observa en la figura 5.
Figura 5. Los registros de las piezas están separados de los registros del auto
El
modelo relacional no refleja la estructura de la realidad.
Como
hemos dicho, si un auto contiene piezas,
un objeto de software “Auto” contiene objetos “Pieza”.
Sin embargo, en el modelo relacional, los registros de los
autos y piezas están por separado (esto se muestra
en la figura 5) y se relacionan por un mecanismo implícito
llamado “clave foránea”.
El programador debe saber que hay una relación entre
los autos y las piezas y debe programar de acuerdo a ello.
Sin embargo, el modelo no refleja explícitamente esta
relación y, en general, la estructura de la realidad,
al contrario del modelo orientado a objetos.
3.
APLICACIONES TRADICIONALES.
Como
conclusión de lo que se ha dicho hasta ahora,
una aplicación está formada por un programa
y una base de datos que se comunican entre sí. El
programa suele estar diseñado según el modelo
orientado a objetos y, por lo tanto, trabaja con datos en
formato de objetos. Por el contrario, la base de datos está diseñada
según el modelo relacional y, por lo tanto, trabaja
con datos en formato de registros. Esto introduce una dificultad
importante, porque los dos formatos de datos (objetos y registros)
son incompatibles entre sí. Así, cuando el
programa quiere guardar o recuperar los datos en disco (para
que no se pierdan entre ejecuciones), lo hace n forma de
objetos, pues es el formato de datos que conoce. Sin embargo,
la base de datos no puede guardar o recuperar objetos, pues
está diseñada para guardar o recuperar registros
(y no objetos), que es el formato de datos que ella reconoce.
Esto se muestra en la figura 6. Resumiendo, los formatos
de datos que utilizan el programa y la base de datos son
incompatibles
entre sí.
Podemos decir que el programa y la aplicación hablan “idiomas
diferentes” y, por lo tanto, debemos encontrar una
solución para que se comuniquen.
Figura 6. El programa y la base de datos usan diferentes formatos de datos
La
solución más obvia a este problema es hacer
que uno de los componentes hable el idioma del otro. Es decir,
que un componente use el formato de datos del otro. Así,
la primera opción que examinamos en este artículo
es la de que el programa esté diseñado para
tratar con datos relacionales, la cual se refleja en la figura
7. En esta opción, tanto el programa como la base
de datos hablan un mismo idioma: el relacional y utilizan
como formato de datos el de registro. Por lo tanto, la comunicación
es posible.
Figura 7. Arquitectura de una aplicación tradicional
Ésta era la forma de programar universalmente adoptada
antes de la aparición de la orientación a objetos
y sigue siendo la arquitectura dominante en El Salvador.
Aún entre las empresas que utilizan lenguajes orientados
a objetos, la mayoría programa sin tener en cuenta
la orientación a objetos a la hora de usar los datos,
los cuales se gestionan de forma relacional.
El
problema de esta arquitectura es que se desaprovechan las
grandes
ventajas de flexibilidad, facilidad de mantenimiento
y facilidad de gestión de sistemas complejos que da
la programación orientada a objetos. Asimismo, el
código que opera con datos relacionales suele ser
complejo, difícil de mantener y de ampliar y muy dependiente
de la estructura de los datos.
4.
BASES DE DATOS ORIENTADAS A OBJETOS.
Como
hemos visto en el apartado anterior, la opción
consistente en que toda la aplicación use un mismo
modelo teórico relacional no es la más adecuada.
Examinemos ahora la opción en que toda la aplicación
tenga un único modelo teórico, pero que éste
sea el de orientación a objetos. Esta opción,
que se refleja en la figura 8, implica que el formato de
datos que usa toda la aplicación es el formato de
objetos.
Figura 8. Arquitectura de una aplicación con base de datos orientada a objetos
Para
un programa resulta natural trabajar con objetos. Sin embargo,
esto es imposible para las bases de datos tradicionales,
basadas en el modelo relacional. Para resolver este problema
han aparecido las bases de datos orientadas a objetos. Al
contrario de sus homólogas relacionales, que trabajan
con registros, las bases de datos orientadas a objetos guardan
y recuperan objetos. Por lo tanto, la comunicación
de este tipo de base de datos con un programa orientado a
objetos es posible.
Aunque,
sobre el papel, ésta es la mejor opción para
implementar una aplicación de base de
datos, en la práctica presenta una serie de problemas
importantes, debido a las características actuales
de las bases de datos orientadas a objetos. Éstas
no están tan maduras como sus homólogas relacionales
y, por lo tanto, no gozan de la abundancia de herramientas,
la fiabilidad, facilidad de administración y rendimiento
de estas últimas.
Lo
que es peor, las bases de datos orientadas a objetos frecuentemente
son incompatibles entre ellas. Esto hace imposible
migrar una aplicación desde una base de datos orientada
a objetos a otra, lo que nos obliga a depender de un único
proveedor (fenómeno conocido como “vendor lock-in”),
con todas las incoveniencias que esto supone (obligación
de aceptar los aumentos de precio del proveedor, falta
de soporte si el proveedor sale del mercado, etc.).
Como
conclusión, aunque ésta pueda ser la
opción preferible en un futuro, en el que las bases
de datos orientadas a objetos alcancen una madurez y estandarización
suficientes, en el presente resulta arriesgado aplicarla.
5.
MOTORES DE PERSISTENCIA.
Hemos
visto que las opciones que se basan en imponer un único
modelo teórico (un único formato de datos)
a toda la aplicación padecen de graves inconvenientes.
En el caso de que toda la aplicación siga el modelo
relacional, perdemos las ventajas de la orientación
a objetos. En el caso de que toda la aplicación siga
el modelo orientado a objetos, tenemos que las bases de datos
que debemos usar están inmaduras y tienen un bajo
nivel de estandarización.
Examinemos
ahora la opción de que el programa sea
orientado a objetos y la base de datos sea relacional, lo
que, en principio, constituye la opción más
natural. Sin embargo, plantea el problema de cómo
hacemos que dos componentes con formatos de datos muy
diferentes puedan comunicarse y trabajar conjuntamente. Siguiendo
la metáfora anterior, se trata de hacer que dos personas
que hablan idiomas diferentes se comprendan.
La
solución es la misma que se daría en la
vida real. Se debe encontrar un traductor
que sepa traducir de cada idioma al otro. De esta forma,
las dos personas se entenderán sin necesidad de que
uno hable el idioma del otro. En el mundo de la programación
este traductor no es más que un componente de software
(concretamente, una capa de programación), al que
se le dan los nombres de “capa de persistencia”, “capa
de datos”, “correspondencia
O/R” (“OR mapping”) o “motor de persistencia”.
El
motor de persistencia traduce entre los dos formatos de
datos:
de registros a objetos y de objetos a registros.
La situación se ejemplifica en la figura 9. Cuando
el programa quiere grabar un objeto llama al motor de persistencia,
que traduce el objeto a registros y llama a la base de datos
para que guarde estos registros. De la misma manera, cuando
el programa quiere recuperar un objeto, la base de datos
recupera los registros correspondientes, los cuales son traducidos
en formato de objeto por el motor de persistencia.
Figura 9. Arquitectura de una aplicación con motor de persistencia
El
programa sólo ve que puede guardar objetos y recuperar
objetos, como si estuviera programado para una base de datos
orientada a objetos. La base de datos sólo ve que
guarda registros y recupera registros, como si el programa
estuviera dirigiéndose a ella de forma relacional.
Es decir, cada uno de los dos componentes trabaja
con el formato de datos (el “idioma”) que le
resulta más natural y es el motor de persistencia
el que actúa de traductor entre los dos modelos, permitiendo
que los dos componentes se comuniquen y trabajen conjuntamente.
Esta
solución goza de las mejores ventajas de los
dos modelos.
Por una parte, podemos programar con orientación
a objetos, aprovechando las ventajas de flexibilidad, mantenimiento
y reusabilidad.
Por otra parte, podemos usar una base de datos
relacional, aprovechándonos de su madurez y su estandarización
así como de las herramientas relacionales que hay
para ella.
Se
calcula que un motor de persistencia puede reducir el código de una aplicación en un 40%, haciéndola
menos costosa de desarrollar. Además, el código
que se obtiene programando de esta manera es más limpio
y sencillo y, por lo tanto, más fácil de mantener
y más robusto. Por añadidura, el motor de persistencia
no sólo simplifica la programación, sino que
permite hacer ciertas optimizaciones de rendimiento que serían
difíciles de programar por nosotros mismos.
Como
conclusión, ésta es la mejor opción
en la actualidad para implementar una aplicación de
software.
6.
OPCIONES PARA MOTORES DE PERSISTENCIA.
Una
ventaja del motor de persistencia es que es el mismo para
todas
las aplicaciones. De esta forma sólo debe
programarse una vez y puede usarse para todas las aplicaciones
que se desarrollen en nuestra empresa. Sin embargo, un motor
de persistencia es difícil de programar y de mantener,
por lo que necesita un gran esfuerzo en costo y tiempo de
desarrollo.
Es por ello que hay dos opciones a la hora de usar un motor
de persistencia:
Programarlo dentro de nuestra empresa. Como se
ha dicho, esto no es lo más recomendable, por la complejidad
y costo que introduce esta opción.
Utilizar un motor que ya esté programado,
comprándolo a un vendedor o bien usando un motor gratuito
de código abierto.
Se
recomienda fuertemente la segunda opción, que
es la menos costosa y la menos propensa a fallos. Se debe
escoger un motor de persistencia de los que están
programados, estudiarlo y aplicarlo a todas las aplicaciones
de una misma empresa. A continuación, explicamos algunos
de los motores de persistencia más importantes para
la plataforma Java y para la plataforma .NET, con el fin
de que el lector pueda comenzar una investigación
que le lleve a escoger el que más se ajuste a sus
necesidades.
En
cuanto a la plataforma Java, los servidores de aplicaciones
basados
en la especificación EJB (“Enterprise
JavaBeans”), incorporan un motor de persistencia a
través del mecanismo conocido como “entity beans”.
Sin embargo, los “entity beans” no son un mecanismo
de persistencia totalmente recomendable, pues no permiten
implementar algunas características de la programación
orientada a objetos (por ejemplo, herencia) y además,
obligan a una forma de programar diferente a los objetos
normales de Java (o POJOs, por “Plain Old Java Objects”)
.
Hay
motores de persistencia más completos que no
tienen este tipo de inconvenientes que se acaba de mencionar.
Entre los de código abierto podemos destacar: Hibernate,
Castor, Torque, OJB y Cayenne. Entre los comerciales, podemos destacar
TopLink, Cocobase y FastObjects. En los últimos años
se ha creado una especificación llamada JDO, para
estandarizar la forma de programar en Java con esos motores
de persistencia. Ejemplos de motores de persistencia que
cumplen el estándar JDO son Kodo, JDO Genie, LiDo, Exadel JDO, IntelliBO, JRelay JDO
(todos ellos comerciales), Speedo JDO, TJDO y XORM (de código abierto).
La
plataforma .NET, por su relativa novedad, está más
inmadura que la plataforma Java. Además, al ser una
plataforma propietaria, cuesta más encontrar proyectos
de código abierto para ella. Por todo ello que no
hay tanta variedad de motores de persistencia en esta plataforma.
Recientemente, Microsoft ha anunciado un motor de persistencia
llamado Objectspaces para .NET 2004. Mientras tanto,
se puede usar ORM.NET,
que es un motor de persistencia comercial para .NET.
Compruebe la calidad de nuestro desarrollo offshore.
Aurum Solutions tiene experiencia en desarrollo offshore en
J2EE y .NET de alta calidad y reducidos costos para empresas
europeas y norteamericanas. Conozca nuestro
desarrollo offshore haciendo
clic aquí o
en la página Web ../../offshore.html.
Cursos de Aurum Solutions relacionados con el tema de este artículo:
“Persistencia para Java”.
“Java Data Objects (JDO)”.
“Enterprise Javabeans”.
“Persistencia para .NET”.
Nota de copyright: Este documento puede
ser impreso, copiado y utilizado en cualquier forma que se
considere conveniente, siempre que se respete su integridad,
el nombre de su autor y el enlace ../../index.html a
la empresa Aurum Solutions, S.A. de C.V.
|