Encuesta

¿Qué sistema operativo empleas principalmente cuando desarrollas Java?

28-02-2010 - 878 votos

Destacados Agenda

Más eventos |

(2)

JavaHispano Podcast - 005 - Mapeo de Objetos Relaciones (ORM)

20/12/2007 15:43 JorgeRubira

Publicado número 5 de javahispano Podcast.

Sección de noticias: Presentado por Abraham, ECamacho y Alfredo Casado

Seccion Tertulia: Mapeo de objetos relacionales (ORM). Explicaremos que es y comentaremos algunos frameworks como Hibernate, JPA, JDO, IBatis. Presentado por Alberto Molpeceres, Sergi (Squatter), Eduardo Millan, Alfredo Casado, Ignacio Andreu y Jorge Rubira

Volver a actualidad

Etiquetas: j2ee

Comentarios: 45

  • Anónimo 20/12/2007 15:39

    El RSS no se ha actualizado

  • JorgeRubira 20/12/2007 15:44

    Creo que tarda un poco en actualizarse.

  • Marioko 21/12/2007 14:32

    como siempre excelente podcast!!

     Sobre el ORM tengo una duda que desde que uso ORMs (Hibernate, JPA) me ha rondado la cabeza, debido a las capas que manejan estas implementaciones, ¿puede una app que use ORM ser igual de rapido en el acceso a la BD a una que unicamente utiliza JDBC?? SI asi  es, que estrategias se podrian utilizar? Me imagino algunas pero nose si pudieran tener las misma velocidad de acceso a la BD.

  • Anónimo 22/12/2007 21:04

    Preguntar si un ORM puede ser rápido es parecido a preguntar si Java es rápido. La respuesta fácil es "a veces", porque no es lo mismo leer que escribir, usar vistas o procedimientos que no utilizarlos, necesitar muchos o pocos datos de un objeto, coger esos datos para manipularlos que para mostrarlos unicamente. Eso sin entrar a definir que es "rápido".

    Un sistema ORM puede usar cachés, puede utilizar actualizaciones masivas, lo mismo que un programador torpe puede hacer las cosas mal con jdbc y no cerrar una conexión (o no usar pool). Y lo mismo al reves, hay ORMs escritos por torpes y grandes programadores de bajo nivel. Al usar un ORM "confias" en que cosas "tediosas" las puedas hacer de forma sencilla, pero siempre hay casos en los que un ORM no es la mejor opción (por ejemplo lecturas masivas, como bien se dice en el podcast).

    Hay una cosa que me parece curiosa, una más. Y es que gente que ha "desbarrado" mucho sobre los entities de EJB2, "apoye incondicionalmente los ORM", cuando la idea es la misma, y los problemas en gran parte también.

  • greeneyed 23/12/2007 12:54

    Hay una cosa que me parece curiosa, una más. Y es que gente que ha "desbarrado" mucho sobre los entities de EJB2,

    Ahi es como en la política, si pudieramos grabar lo que dicen algunos y contrastarlo con lo que dicen un tiempo despues... sería más que cómico :).

    Pero bueno, los problemas de EJB2 que no tienen los ORM de ahora o JPA son otros, lo que pasa es que mucha gente solo sigue las modas en cuanto a preferencias y no se para a averiguar las razones que hay por debajo.

  • batch4j 25/12/2007 18:37

    Estoy siempre en contra de los ORM , cuando las BBDD sean orientadas a objetos los ORM seran interesantes mientras pueden conseguir que un sistema con 2000 tablas se convierta en un sistema con miles de objetos y si cada objeto es una fila y hablamos de millones de filas, por muy bueno que sea el java descargando la maquina virtual, ese sera el punto debil.

  • remoh 25/12/2007 20:08

    No estoy de acuerdo bartch4j, los datos que lees de la bd tienen que estar en memoria si quieres tratar con ellos, da igual que uses un ORM o no lo uses, los datos ocupan espacio en memoria de igual modo.

    usar un ORM no tiene que provocar que desperdicies memoria de forma innecesaria ni muchisimo menos, que desperdicies o no memoria dependerá de como diseñes tu aplicación y de cuanto cuidado pongas en estas cosas, un ORM usado con cabeza ahorra trabajo y muchas lienas de código, evidentemente si lo usas sin saber lo que pasa por debajo puedes cometer burradas, pero vamos soy e la opinión de que el que comete burradas usando un ORM también las va ha cometer usando JDBC a pelo...

     

     

  • hugonet 26/12/2007 00:13

    De nuevo un excelente podcast, muy interesante el tema tratado.

    Estoy de acuerdo con la opinión de los panelistas que hay que conocer primero el JDBC y SQL 'manual' o 'conceptual' antes de emplear ORM. Siempre es mejor ir de abajo hacia arriba, asi cuando se presente agún problema que un framework o un ORM no nos pueda resolver sabremos que hacer si conocemos los fundamentos. En cuanto a los procedimientos almacenados, considero que es mejor utilizarlos solo cuando sea indispensable,para asi no dejar lógica en la BD.

    Gracias por este trabajo tan interesante que hacen, me gustaria escuchar en futuras entregas :

    • Comparación con ventajas y desventajas de los frameworks para aplicaciones web tal como Spring, Tapestry, Struts etc... los principiantes a veces nos confundimos con tanta terminología.
    • También sería interesante un debate con las ventajas y desventajas de los principales IDE para Java (Netbeans, Eclipse, InteliJ IDEA, etc...). No se trata de decir cual es mejor sino de dar una orientacion de los puntos fuertes y débiles de cada uno de ellos.
    • Control de versiones, importancia, como hacerlo, herramientas, CVS, Subversion,

    Se me quedan algunos temas a recomendar, pero seria un atrevimiento!. :D

    Un Feliz y próspero 2008 a todo el equipo de javahispano y a los desarrolladores java en Europa y América que visitan este fantástico portal.

  • Anónimo 26/12/2007 10:35

    batch4j ..... una aplicación con 2000 tablas va a ser un follón SI o SI.

    Pero en todo caso, 1 tabla != 1 objeto, de modo que tu 'argumento' (?) no es válido. Aunque estoy con Remoh, normalmente el problema no es la tecnología/herramienta, el problema es quién la utiliza.

  • jpox 27/12/2007 15:40

    Señor batch4j, donde esta tu argumento? Si tienes un RDBMS, la cosa de ORM o no ORM es simplemente una balanza entre el tiempo necesario para escribirlo en JDBC y el tiempo para hacer la misma cosa con un ORM, nada mas. Escribo un ORM pero no estoy en favor de utilizarlo en todas las situaciones. Pero tener una cantidad de relaciones entre objetos y querer persistencia transparente deja una eleccion ... ORM. La rapidez puede alcanzar a JDBC con el uso de la cache. Con un ORM que usa cambios de bytecode ganas tambien en la rapidez de saber que campos han cambiado sin la necesidad de comprobar todos. Es la misma cosa con cada tecnologia ... usala cuando sea apropiado.

  • Anónimo 28/12/2007 06:03

    Veo que estoy muy desactualizado. Pensaba que el poner la lógica del lado de la aplicación era una mala práctica y que por eso se dejó de usar hace ya varios años, pero veo que esa tendencia está volviendo.

    ¿Alguien me podría explicar por qué tengo que relegar a un SGBD, que ha sido especialmente diseñado para manejar datos, como un simple almacén de datos?

    Veo que lo que aprendí del libro de C. J. Date ha perdido validez.

    Supongo que tendré que aprender a usar uno de esos ORM's.

  • JorgeRubira 28/12/2007 16:19

    En mi opinión siempre depende de la circunstancia y buscar un equilibrio entre rendimiento y mantenibilidad. Hay casos en los que los ORMs pueden perjudicar cuando se busca velocidad en las operaciones por haber multitud de registros ("no tablas") y hay otros casos en que desarrollar directamente el procedimiento almacenado hace más compleja tu aplicación (si no estás acostumbrado por ser programador habitual de java).

    Si eres programador habitual en bases de datos, no veo razón para cambiar a un ORM. Pero si eres programador habitual java acostumbrado a POO y cada vez que tienes que tocar un procedimiento almacenado, te entra pánico, puede ser una razón para mirar algun ORM y así no trabajar con RecordSets.

    Otra "desventaja" que no se ha hablado de los ORMs es que la aplicación servidor (que accede a la BD) tiene que estar en el mismo lenguaje. Si quieres ejecutar la misma logica desde java, php, .net, etc. o diseñas una arquitectura SOA o centralizas la lógica en la BD. Esta problematica suele estar en sistemas grandes (a ojo de mal cubero sería un 30% de los programadores) donde trabajan multitud de empresas en el mismo sistema y cada parte es diferente según la empresa. En estos sistemas suele ser más habitual la arquitectura SOA. En un 10% tendríamos el caso de pequeños sistemas donde se desarrollaría la misma lógica en diferentes lenguajes (normalmente para uso interno en la empresa) lo que una arquitectura SOA perjudica por "matar moscas a cañonazos". Ej: Una aplicación que tenia VB6, luego se hizo una web JSP o PHP y además ahora el informatico está haciendo otro modulo en Ruby (por ir probando a ver que tal) y  se ejecutan los mismos algoritmos desde ambos leguajes según si entran por internet, intranet, canal moviles, etc pero con diferentes lenguajes. En este caso, programar en la BD estos algoritmos puede ser una buena idea por programarse solo una vez y centralizar la lógica en un sitio. (Despues de todo si el sistema tiene muchos lenguajes, otro más no desentonaria :) )

  • Anónimo 28/12/2007 20:09

    Desventaja de ORM tiene que estar en mismo lenguaje??? Si usas un ORM es en vez de algo. Si tienes un RDBMSy usas Java, seria en vez de JDBC. Asi que es independiente de lenguaje. Claro que hay algunos lenguajes que no tiene ORM, pero no es una desventaja de un ORM o otro ORM.

    Programar algoritmos en la base de datos ??? Como "stored procedure" quizas ? algo que crece y crece con tiempo ? y no hay seguridad de tipos? y no es una manera comoda para desarrollar logica ? Si. He visto sistemas asi ... me parecen unos abortos.

  • Anónimo 30/12/2007 13:30

    Yo no creo que por tener que usar SQL iBATIS deje de ser un ORM. Realmente mapea objetos con el modelo relacional.

    Lo que no hace es establecer un modelo particular de mapeo, sino que tienes que definir tú el mapeo. Pero no creo que por eso deje de ser un sistema de mapeado objeto-relacional.

  • batch4j 31/12/2007 19:25

    La verdad es que no tengo ningun argumento, a parte de mi experiencia, que seguramente no coincidira con la vuestra, para mi es fundamental no tener miles de objetos distintos, si bien una tabla no es un objeto, seguramente al utilizarlo en un ORM al final lo sera.

    Normalmente trabajo a bajo nivel, lejos de la logica de negocio por lo que es mas facil no tener miles de objetos, es mejor tener un numero restringido, pero es solo mi opinion.

  • Anónimo 01/01/2008 02:55

    Imposible procesar la plantilla:FreemarkerTemplate: poll/activa.html Page: poll/activa.html. Expression poll is undefined on line 7, column 8 in default/poll/activa.html.

    Salio este texto en el lado izquierdo de la pàgin, debajo del título "publicar contenido"

  • supertorpe 01/01/2008 22:36

    Esta discusión parece más propia de un foro que del apartado de noticias, pero ya que estamos... uno de los problemillas de los ORM (por lo menos de JPA) son consecuencia de su propia naturaleza, en contraposición a los modelos orientados a datasets (o recordsets, o rowset, o resultsets...) como JDBC. El problema es que muchas veces no necesitamos todos los atributos de una entidad y mientras que con SQL yo hilo fino con el SQL y me traigo en un dataset sólo la información que necesito, el ORM me trae la entidad con todos sus atributos (igual es ignorancia mía y hay alguna forma de decirle que sólo cargue algunos atributos). Aún si hubiera alguna forma de decirle que me traiga algunos atributos de la entidad, ello me generaría otros problemas: si paso esa entidad a otras capas de la aplicación ¿cómo saben que el resto de atributos no están cargados o son realmente null? Para solucionarlo podría crear versiones recortadas de la clase. Pongo un ejemplo: si tenemos una clase Persona que representa la tabla PERSONAS y manejamos información de las personas en diferentes contextos (p.e. en la pantalla de mantenimiento de personas, en un listado de personas, en otro listado donde aparezca un subconjunto de los atributos de las personas) tendría que crearme varias clases Persona: PersonaListado, PersonaResumen... mapeando todas a la tabla PERSONAS y usando una u otra según la circunstancia, lo que provocaría una proliferación de clases desmesurada, con lo que genero otro problema más...

    La solución tradicional ha consistido, en lugar de intentar acoplar el modelo relacional al modelo objeto es continuar trabajando con el modelo relacional (dataset), tal y como hace JDBC.

    No obstante, yo intentaré usar JPA donde pueda por la comodidad y los servicios que me ofrece de forma transparente (caché, lazy-loading...)

  • Anónimo 02/01/2008 07:27

    @supertorpe, JDO es la unica especficacion que ofrece "fetch-groups" - el control sobre que campos estan cargado en el objeto. JPA no ofrece nada de esa forma. Y que pasaria si un campo no esta cargado ... con JDO puedes ver que campos estan cargado o no, y enviar otra pedida a la capa de base de datos.

  • Anónimo 02/01/2008 10:22

    Sugerencia.... estaría bien algo así como "ampliaciones del podcast". Que los comentarios o preguntas que salgan aquí se hagan llegar a los participantes del podcast y que se contesten/comenten/revatan esas opiniones de los oyentes en el siguiente podcast.

  • Plunchete 02/01/2008 15:00

    @supertorpe

    Desde mi punto de vista lo que haría sería definir varios NamedQuery de tal forma que tengas uno por cada tipo de carga de ese objeto que desees hacer, así en vez de tener varias clases podrías hacer, por ejemplo:

    @NamedQuery(
    name="findPersonasByName",
    query="SELECT p.nombre, p.mail FROM Persona p WHERE p.nombre LIKE :nombre"
    )

    Y ejecutarla de la forma:

     em.createNamedQuery("findPersonasByName").setParameter("nombre", nombre).getResultList();
    Si haces la consulta en una parte que no es y se lo pasas te va a ocurrir lo mismo que te ocurriría usando JDBC, ya que ahí también eliges qué se carga en cada consulta SELECT. Además, hay que tener mucho cuidado con la carga perezosa, como bien se dice en el podcast.

    Un saludo!

    - Ignacio Andreu

  • remoh 03/01/2008 14:39

    tendría que crearme varias clases Persona: PersonaListado, PersonaResumen... mapeando todas a la tabla PERSONAS y usando una u otra según la circunstancia, lo que provocaría una proliferación de clases desmesurada, con lo que genero otro problema más...

    Pues esta primera solución que propones es en mi opinión la buena, lo que no veo que sea un problema es la "proliferación de clases", tener mucha clases no es malo, siempre y cuando estas clases representen diferentes cosas, las clases no son estructuras de datos, a esos datos los acompañan una serie de comportamienos (métodos) y si cargas diferentes datos de una tabla para diferentes casos de uso también parece logico que estas clases incorporen comportamientos diferentes. Precisamente en esta situación tener más clases no es un problema, es un claro beneficio porque consigues una mejor separación de conceptos en tu código.

    Este es precisamente uno de los problemas de "la impedancia objeto-relacional" la diferencia de granularidad de los dos modelos, la relación entre tablas y clases no tiene porque siempre 1:1 , una cosa es definir las clases que tienen sentido en un módelo de objetos y otra cosa son las tablas que tengo en la BD.

    Por ejemplo el caso que comentas de "Persona y PersonaResumen", es un ejemplo muy simple donde parece que sólo vamos a cojer los datos de bd para presentarlos en un listado resumido, incluso en este caso tan sencillo ya se pueden ver algunas de las ventajas de tener una buena separación de conceptos:

    - Si quiero ver que datos se presentan en el resumen, en el caso de que tenga un dataset tendré que ver como esta construida la query para ver que datos se presentan. En el caso de que tenga un clase PersonaResumen puedo mirar sus propiedades y ya se lo que puede incorporar un resumen. O incluso hacer un método "getResumen" que me devuelva la linea de resumen. Es decir, con un dataset la información de como se construye un resumen esta en detalles del código (querys sql, ver que datos se cojen para formar el resumen mirando el codigo), en el caso de tener una clase PersonaResumen tengo esta información explicitamente diseñada en mi módelo, mejor separación de conceptos.

    - Si tengo una separación en capas donde una persona distinta se encarga de la vista, es preferible que a quien este haciendo la vista le llegue una lista de clases PersonaResumen a cualquier otra cosa, ya sea un dataset o una clase Persona parcialmente cargada. En la vista se trabaja contra clases que ya me están definiendo que datos tengo que presentar en el resumen y sólo me tengo que preocupar de como presentarlos, que es lo que se supone que tengo que hacer en la vista, es decir, de nuevo tengo un diseño más claro que favorece una mejor separación de conceptos. En el caso de que a la vista le llegue un dataset el autor de la vista tienen que conocer incluso los nombres de las columnas en la bd, algo que no tiene porque conocer alguien cuyo trabajo es pintar bonito un resumen.

    Más clases no es igual a más complejidad, no nos tiene que importar el número de clases cuando hacemos un diseño orientado a objetos, nos tiene que importar cuanto de bien o mal esas clases representan el dominio con el que estamos trabajando. Un código donde para extraer la información de que hace tal caso de uso o como se presenta tal listado me obliga a investigar en el código leyendo las querys o mirando en detalle como se obtienen los datos y qu se hace con ellos, es más complejo y difcil de entender/mantener que un código donde tengo clases que representan con claridad los mismos conceptos que antes estaban dispersos en una maraña de código.

  • Plunchete 03/01/2008 15:01

    Pues esta primera solución que propones es en mi opinión la buena

     

    Eso quiere decir que la mía no te gusta? Vaya ... jejeje. La verdad es que el uso del NamedQuery me parece una alternativa más sencilla, para este caso en concreto, cada NamedQuery en cada entidad a la que pertenece y de esa forma no hace falta mirar cada clase PersonaXXX para ver qué es lo que hace, sino que de un vistazo a la clase Persona vemos qué queries posee y qué hace cada una de ellas. Lo que si que es cierto es que cuando pasemos a hacer SELECTs con relaciones entre clases/tablas la cosa se complica, con lo que yo optaría por una solución mixta.

  • remoh 03/01/2008 16:34

    Lo que no me gusta de usar namedquerys en este caso concreto es que se estarían devolviendo clases Persona parcialmente cargadas. Imagina que estoy en la capa de vista y me llega un objeto Persona parcialmente cargado, entonces me toca mirar dentro de la capa de persistencia para ver que valores se han recuperado y a que cosas puedo o no puedo acceder para hacer mi vista de resumen.

    Lo ideal es que el contrato entre las distintas capas lo establezca el interfaz de las clases de modo que no tenga que meterme a ver detalles de implementación concretos para averiguar porque no puedo acceder al campo X al que accedo normalmente desde otras vistas sin ningún problema.

    Además que esto de tener clases que no están cargadas del todo no me gusta un pelo, tarde o temprano te va a terminar dando problemas porque ahora necesitas mostrar el campo X, y alguien dira, anda si en la clase hay un método getX!!, y luego pum! sorpresa esta a null o lanza una excepción al intentar acceder.

    De todas formas este caso es muy simple, la idea de fondo es que las clases son algo más que simples "estructuras de datos", si luego la clase persona tiene métodos, que logicamente utilizarán algunas de su propiedades, en algunos casos funcionaran y en otros no dependiendo de que campos haya o no haya cargado en la query concreta. Esto en mi opinión a la larga puede resultar en algo bastante confuso y un lio de narices si no se anda con mucho ojo.

     

  • venkman 03/01/2008 16:55

    Desde un punto de vista ajeno al mapeado OR... ¿realmente os parece razonable que alguien necesite (o crea que es necesario o conveniente) crear PersonaListado, PersonaResumen, PersonaDeFrente, PersonaDeLado, PersonaBailando...?

    Veamos, a mi esto ni siquiera me parece que sea un problema relacionado tanto con la persistencia como con el diseño de la aplicación. Imaginemos por un momento que nos olvidamos de usar un ORM. ¿Deja de ocurrir el problema que comentas, supertorpe? Entiendo, por lo que comentas, que pretendes "hilar más fino con el SQL" trayendo sólo los atributos que necesitas según la vista actual. Bien, ¿pero cómo desaparece el problema ahora que no usamos ORM? ¿O es que realmente el problema no es el mapeado OR si no el hecho de que quieres tener diferentes objetos según cómo se les vea?

     

    A donde quiero llegar es a: Una Persona es una Persona. Si voy por la calle y me cruzo con 17 personas, sólo veo su apariencia externa y poco más. Pero no por eso dejan de tener un montón de información más que yo no estoy viendo ni utilizando. Si paro a una de esas personas y le hago una encuesta, no cambia la Persona para tener más información ahora. Es la misma.

    Lo que quizá deberías plantear es... ¿estoy tratando de hacer que los objetos de mi dominio dependan de la vista en la que los veo? Porque me parece que ese es procisamente el caso. Tienes un objeto del dominio de tu aplicación que es una Persona, con una serie de propiedades. Son de la Persona esas propiedades. La Persona no cambia de propiedades según vayas a sacarla en un listado, imprimir su ficha o verla en la agenda de teléfonos. Lo que cambia es la vista, la información que en cada caso quieres ver de ese objeto, pero no la que tiene. ¿Qué es un Resumen de una Persona? ¿Es realmente un objeto del dominio con una entidad propia? ¿O quizá es sólo una forma de ver un objeto Persona?

     

    Ahora bien, otra cosa es que pueda ser razonable tener, en tu dominio, una Persona distribuída en más de un objeto. Por ejemplo, podrías tener una Persona con unas propiedades básicas (nombre, peso, altura, sexo), 1 o más Direcciones, 1 o más Empleos, 1 o más RasgosFisicosNotables. Cuando sólo quieres sacar el listado, no traes las Direcciones, Empleos o RasgosFisicosNotables, porque sabes que no los vas a usar. Esas propiedades estarán vacías... o no... realmente a tu vista le da igual porque no va a mirar eso.

     

    Preguntas: "¿cómo saben que el resto de atributos no están cargados o son realmente null?" Y digo yo, ¿le importa a la vista de listado saber si una Persona no tiene Empleos o si es que no se han cargado? Lo único que necesita tu vista es que la Persona que recibe tiene cargadas las propiedades que va a usar. Las que no va a usar... ¿qué más me da?

     

    "Para solucionarlo podría crear versiones recortadas de la clase."

    No sé si decir directamente que me parece una mala idea... El problema es que... ¿realmente tienen entidad propia esas "Personas Recortadas"? ¿Tienen algún sentido en el dominio de tu aplicación? OJO! No si tiene sentido para una vista particular ver a una Persona de un determinado modo, lo que pregunto es si tiene sentido/entidad propia esa vista como un objeto del dominio.

    Ahí, en mi muy humilde -y probablemente equivocada- opinión (pero que como es mía pues oye, la comento): No. Lo que estarías haciendo así es liga, atar, los objetos de tu dominio a una particular vista. Es decir, realmente lo que estás planteando es romper la separación entre el modelo y la vista.

    No es que me quiera poner aquí a discutir si eso es horrible o sólamente malo, pero creo que si hablamos de utilizar un sistema de ORM, entonces nos movemos ya en un ambiente en el que sí, queremos tener una arquitectura sólida. Si vamos a tener un modelo mezclado con la vista... usar SQL "a mano" me parece que es... poco relevante.

     

    (No me peguéis muy fuerte, no vaya a ser que me duela. Gracias)

  • ibon 03/01/2008 17:51

    Yo de hecho estoy de acuerdo contigo Venkman... :-) Me estaba recordando el anti-patrón J2EE value objects... pero bueno, que a mi me parece un anti-patrón... :-)

  • remoh 03/01/2008 18:15

    jeje, faltaba venkman para llevame la contraria... es broma.

    Mal ejemplo el de los listados, es cierto que puede parecer que estamos atando el módelo con la vista si hacemos algo así, y no tiene mucho sentido que porque mañana el cliente necesite una vista tenga que modificar mi módelo cuando el dominio no cambia, sólo la forma de verlo, en eso estamos de acuerdo.

    Lo que tampoco es desde mi punto de vista una buena idea es tener objetos cargados a medias, aunque en la vista X no vaya a usar la propiedad X una Persona sigue siendo una Persona, por ejemplo, si la persona tiene un método "responderEncuesta(Encuesta e)" no puede ser que me devuelva una excepción diciendome "perdon pero no puedo responder porque no me cargarón el cerebro". :P

    El módelo tiene que ser consistente, no me gusta la idea de tener personas circulando por mi aplicación unas sin cerebro, otras sin corazon, otras sin ropa (que escandalo! xd), es que esas cosas no son personas, son en todo caso una vista parcial de una persona o "DatosPersonaParaResumen" que es una clase que no forma parte de mi módelo de dominio, que sólo la utilizo cuando tengo un caso de uso tan simple como un informe resumido donde lo único que necesito es que la capa de persistencia me devuelva esos datos y listo. Y además se da el caso de que la tabla persona contiene una miriada de datos y sólo quiero leer unos pocos para el resumen y realmente con esto consigo un aumento en el rendimiento (que sino leo personas enteras siempre, y es discutible que con esto consiga una gran mejora, dependerá de muchos factores)

    Desde el punto de la arquitectura tendre casos complejos donde el controlador hable con la persistencia esta le devuelva objetos de mi módelo de dominio (personas enteras) y yo manipule o envie mensajes a esos objetos para hacer lo que tenga que hacer. Luego se pueden presentar casos más simples donde el controlador hable con la capa de persistencia y este le entregue simplemente DTO's y la vista los presente. A mi me parece un enfoque más sólido que tener pululando personas a medias por la aplicación y que los interfaces me mientan, me explico, si un interfaz me devuelve una persona pues eso es lo que yo espero, no sólo un cacho, si sólo me devuelve un cacho tengo un interfaz que miente y esto me parece bastante grave si queremos algo solido.

  • ibon 03/01/2008 18:27

    "A mi me parece un enfoque más sólido que tener pululando personas a medias por la aplicación y que los interfaces me mientan, me explico, si un interfaz me devuelve una persona pues eso es lo que yo espero, no sólo un cacho, si sólo me devuelve un cacho tengo un interfaz que miente y esto me parece bastante grave si queremos algo solido"

    Si remoh, pero una "persona" en tu aplicación no tiene porque modelar a una persona del mundo real, o acaso le ponemos métodos para comerse las uñas? ;-) O acaso una persona que dentro sólo tenga un array de Características... no es una persona? Generalmente estas clases (PersonaListado) me suelen aparecer en mis proyectos cuando la he cagado diseñando el dominio. Y generalmente es porque me he olvidado de que estoy programando en un lenguaje orientado a objetos, y simplemente había creado unas estructuras de datos.

    Asi que sigo de acuerdo con Venkman.

  • remoh 03/01/2008 18:46

    Si remoh, pero una "persona" en tu aplicación no tiene porque modelar a una persona del mundo real, o acaso le ponemos métodos para comerse las uñas? ;-) O acaso una persona que dentro sólo tenga un array de Características... no es una persona?

    Claro que no se tiene porque modelar tal y como lo es en el mundo real, yo no he dicho eso, es una persona en el contexto de mi dominio de aplicación, lo que estoy diciendo es que si en mi contexto una persona esta definida por x,y,z no me gusta tener pululando personas a medias que sólo tengan x o y. Porque eso no son personas desde el punto de vista de mi dominio, que es lo que me importa claro.

    Y personalmente no veo ningún problema en tener objetos que en realidad son sólo estructuras de datos, y no es que me este olvidando de la programación OO, simplemente es que en ocasiones sólo quiero enviar datos de un lado para otro (de la bd a la vista, entre objetos remotos) y esos objetos no tienen asociado ningún tipo de comportamiento. Hay situaciones donde es perfectamente razonable y no creo que sea un indicativo de mal diseño ni mucho menos.

    dos contra uno, panda de cobardes xd

  • ibon 04/01/2008 09:16

    jejejejejeje.... ;-)

    Pero a lo que ibamos, si la vista lo que muestra es Características de la persona, lo que tú tienes es completamente cargadas las Características. No medias Personas pululando, sino Características totalmente cargadas. No veo el problema la verdad (salvo que los humanos "interpretemos" realmente que un objeto TIENE que ser un objeto del mundo real, en el que no existen "Características" marchando por la calle). Hay un artículo de Martin Fowler sobre posibles diseños a la hora de tratar con propiedades de un objeto que a mí me abrió los ojos hace tiempo: martinfowler.com/apsupp/properties.pdf , aunque ya te digo que en casa del herrero, cuchillo de palo ;-)

    Sobre la otra cuestión... yo es que me estoy haciendo un poco pijo con esos temas. Ojo, no digo que en mis desarrollos no los use, sólamente que cuando los uso me dejan mal regusto en la boca ;-) Pero que un objeto sólamente tenga sentido para enviar datos, me deja con la sensación de que se podría hacer mejor.... pero ya te digo son mis pajas mentales ;-)

    Salu2

  • Plunchete 04/01/2008 10:41

    Mis comentarios iban, sobre todo, en la línea del comentario de supertorpe.

     

    Muy interesante el artículo que has puesto ibon :-)

  • remoh 04/01/2008 14:57

    si la vista lo que muestra es Características de la persona, lo que tú tienes es completamente cargadas las Características.

    Ese es el tema, que no tengo completamente cargadas las caracteristicas. Tengo algunas si y otras no dependiendo de la query que haya hecho a la bd. A ver si con un ejemplo, ya que estamos con las personas imaginate una aplicación de "libro de familia", las personas tienen nombre, apellidos, dni y número de hijos.

    En esa app tengo una vista resumen que sólo me muestra el nombre y los apellidos de todos las personas que tienen un libro de familia dado de alta en mi sistema. Con vuestro enfoque lo que haría seria devolver una Persona que sólo tiene nombre y apellidos, y tendría a null el dni y el número de hijos, o daría una excepción al intentar acceder a estos valores o haría otra query a la bd para recogerlos, dependiendo de la implementación/configuración del ORM.

    Ahora al tio que esta haciendo el resumen le dicen "oye tron ahora me pones el dni también en el resumen", el tio que no sabe nada de la capa de persistencia va a la interfaz pública de la clase persona y ve que tiene un método getDni(), y responde "en cero coma te lo pongo". Y oh! sorpresas da la vida, el dni sale a null, o la aplicación da una excepción o peor aún, hago una query de más a la bd sin enterarme.

    Esta es la situación que me gustaría evitar, prefiero que el tio se encuentre con una interfaz que no tiene dni y diga "esto hay que hablar con el menda de la persistencia para que me devuelva el dni", que en definitiva es lo que habrá que hacer en cualquier caso, pero en el primero sólo lo puedo descubrir por prueba-error o porque este descrito en algún lugar de la documentación (juas).

    Si una persona tiene que tener dni y número de hijos pues tiene que tenerlos siempre, si no es un diseño incosistente (puede haber propiedades opcionales claro, pero no todas son opcionales), y lo peor es que esa persona cargada a medias a lo mejor tiene 7 hijos en la bd pero cuando llamo a su método getHijos() me devuelve un null!!! (que son hijos = null??, ligadura de trompas??), esto personalmente me parece una guarrada mucho más gorda que los value/transfer objects. A esto me referia antes con que los interfaces me "mienten", si en mi sistema (nada que ver con el mundo real) he definido una persona como algo que tiene nombre, apellidos, dni y número de hijos, cuando estoy manejando un objeto de clase Persona espero que contenga estas caracteristicas y que no me mienta cuando le pregunte el número de hijos (si tiene 7 y devuelve null es mentira y gorda).

    Si trabajo así tengo que confiar en que el encargado de la vista tenga claro que en un momento determinado (cuando esta haciendo el resumen) sólo pude acceder a esta y a esta otra caracteristica, y lo tiene que saber porque se comento en alguna reunión, porque se escribio en algún recondito lugar de la documentación o quien sabe porque. Esto para sistemas medios/grandes me parece algo poco serio.

    ahh, y el articulo de m. fowler, como casi todo lo que escribe, muy bueno y lectura más que recomendable, pero ese intento de poner a fowler de vuestra parte poniendo un articulo suyo es trampa y lo sabes xd

  • ibon 04/01/2008 18:37

    ¿Trampa? Pa que? Creo que ya me conoces y sabes lo que me sudan algunas cosas :-)

    Siguiendo tu ejemplo, remoh, a ver si así no hago "trampas" ;-)... No has entendido "nuestro" enfoque (venkman no ha dicho nada y no sé si está de acuerdo). Persona podría ser (sin seguir el enfoque de Fowler, que sería con propiedades dinámicas y igual hace que no se entienda el objeto):

    public interface Persona {
    public DatosAdministrativos getDatosAdministrativos();
    public Empleos[] getEmpleos();
    public DatosFamiliares getDatosFamiliares();

    ...

    ...

    }

    Y la vista del libro de familia lo que muestra es DatosFamiliares, no una persona, de hecho ni siuiera tiene que saber que una Persona existe! Ahora, el famoso tron de tu ejemplo le dicen que traiga el Dni... ¿que hará? Pues traerse los datos administrativos. NO ha tenido que cargarse una Persona ni usar PersonaParaListadoFamiliar. La vista cambiará, ahora hará uso de DatosFamiliares y DatosAdministrativos, pero coño, es que la vista ha cambiado y es normal que ahora necesite dos. De la otra forma te ves obligado a crear un objeto virtual PersonaConDniEHijos (Para no traerte tropecientosmildatosinutiles), que nunca he tenido claro que es: Modelo o Vista, o ninguna de las dos?

    La vista ha dejado de mostrar Persona, lo que muestra es rasgos de esa persona. ¿Porque hay que modelar una persona con un getDni()? Para mí es un diseño heredado de la base de datos (en el que seguramente tienes una columna llamada DNI en una tabla Persona). El problema del que diseña la vista es que se le hace pasar un peazo objeto Persona y hay que hacer una reunión para explicarle que campos sí y que campos no tiene que meter. De hecho este diseño me parece más claro, y puede servir para que cada uno de los "visteros" se ocupe de una vista particular...

    Yo cuando me ducho no llevo el dni... ¿no soy persona? :-D

    No sé si ahora me he explicado mejor... pero que conste que si no es porque es viernes por la tarde... no pa hacer trampas ;-)

    Salu2

    PD: La siguiente generalización para mi podría ser

    public interface Persona {

    public Caracteristicas[] get();

    public Caracteristica get(Class ImplementacionInterfazCaracteristica);

    }

    Pero eso podría hacer que la interfaz ya no fuera tan clara (aunque sería más genérica, que sería lo OO "correcto", ¿no? :-))

  • greeneyed 04/01/2008 18:42

    Es una de las cosas que me gustan de usar XML como "comunicación" entre modelo y vista, no son interfaces así que no pueden engañarte, jejeje.

    Sobre el tema, lo que creo que quieren decir, remoh, es que ellos no conciben pasar Personas a medias, asi que si tienes un objeto Persona entonces sabes que tiene "todos" los atributos y no hay más. Claro que esto que se dice fácil de atributos simples, no lo es tanto en el caso de objetos relacionados (de ahí mis comillas en el todos :) ).

    En mi caso, tengo que apechugar con otras pegas, pero al menos ese problema no lo tengo por que para cuando llego a la vista, lo que "ves" (el XML) es lo que hay. No hay posibilidad de engaño, ni de llamar a un método para acceder a más información del modelo.

    El artículo de Fowler es interesante, más para gente sin experiencia de campo por que si no ya te lo has encontrado casi todo, pero no da "la solución" por que como el mismo bien indica, no la hay única.

    Y como con esto no se que de lado me pongo, no puedo decir si 3 contra 1, o 2 contra 2... pero ahí queda :P.

  • Anónimo 04/01/2008 19:16

    Hola a todos.

    Yo si me voy a posicionar al lado de remoh y ya tenemos un empate en personas, pero también lo podriamos tener en antipatrones. En el libro J2EE Anti-patterns se habla del antipatron de persistencia Dregde o Deep Query que consiste precisamente en traer todos los datos de un Bean cuando sólo se necesita una parte y como solución se habla de recoger de BD sólo lo que se va a pintar en pantalla y si es necesario (se obtienen mas de 2 campos de BD pej) crear la clase dto correspondiente.

    Y ahora mi opinón. Personalmente yo tengo las clases del modelo en un paquete y las dto en otro, asi me evito "ensuciar" el modelo. Pero reconozcamoslo, en las aplicaciones de hoy en dia, entre el framework web y el de persistencia, los modelos de las aplicaciones suelen tener poco peso.

    Por supuesto que apunto a que lo primero que debe mirarse es si tu modelo esta bien diseñado, la solucion de Persona tiene DatosDeContacto me parece muy correcta, de hecho es normal verla en la tipica clase Usuario. Otra opcion OO sería PersonaExtendida hereda de Persona hereda de PersonaBasica, aunque me quedo con la primera.

    Pero la vida es dura y cuando el cliente nos pide que nuestra aplicacion envie un listado con los nombres y emails de los usuarios a otra aplicacion para hacer un inocente spam seguimos teniendo el problema a pesar de nuestro cuidado diseño y seria un error obtener todos los objetos Persona mas su objeto DatosDeContacto cuando solo queremos el nombre y el email.

    Seamos pragmaticos, no se puede ser mas papista que el Papa, asi que en este caso y similares hacemos la query justa y metemos los nombres en una lista y los emails en otra y a correr o hacemos una lista de objetos de una nueva clase dto NombreMasEmail o ItemListadoSistemaSpam si nos hacen recuperar más de 2 propiedades. Ea pues esa era mi opinion :P

    Un saludo
    César.

  • greeneyed 04/01/2008 19:53

    ..En el libro J2EE Anti-patterns se habla del antipatron de persistencia Dregde o Deep Query...

    Habiendo visto los cambios en las opiniones en patrones y antipatrones a lo largo de la vida de J2EE, ahora JEE, la verdad es que cada vez me fio más del sentido común y menos de la literatura.

    En este caso en concreto, lo que dices va totalmente en contra de los principios de la SoC (separación de conceptos/ámbitos) ya que según esa idea la implementación del "modelo" debería saber en cada caso lo que necesita exactamente la vista.

    Yo en mi caso, excepto en casos extremos y justificados (por rendimiento u otra cosa) yo siempre envío toda la información de la persona y si la vista sólo tiene que usar 2 campos, pues mejor para ella. En mi caso la comodidad/mantenibilidad primero.

    Eso sí, si tengo 52 campos en "persona" y sólo uso una docena de ellos, como mucho, en la mayoría de casos pues ahi lo que hay es un error de diseño.

    Repito y reitero: en mi caso y para el tipo de aplicaciones que yo hago. Cada cual se las componga en su caso :).

  • remoh 04/01/2008 20:33

    ibon pero ese enfoque no es lo que yo estaba rebatiendo, venkman había dicho:

    ¿le importa a la vista de listado saber si una Persona no tiene Empleos o si es que no se han cargado? Lo único que necesita tu vista es que la Persona que recibe tiene cargadas las propiedades que va a usar. Las que no va a usar... ¿qué más me da?

    Yo eso lo interpreto como tener una persona cargada a medias porque en la vista actual me da igual, y eso es lo que quiero evitar. Lo que tu propones es otra historia, aunque tampoco veo claro como funciona, ¿como sería la secuencia de llamadas si por ejemplo quisiera recuperar los Datos administrativos y familiares para un listado concreto?

    - Pido la lista de personas que cumplan una determinada característica a la persistencia

    - A cada una de esas personas les pido primero sus datos familiares y luego sus datos administrativos.

    ok, ¿y que querys hago a la bd?, en el primer dame personas tendré que hacer una query ¿que datos me traigo?, ¿los administrativos y los familiares?, ¿y como lo se si todavía no se que me van a pedir de la persona en cuestión?, me lo puedo traer todo pero entonces no soluciono el problema que estamos discutiendo como resolver (no pedir más datos de los necesarios al usar un ORM, que hablamos de esto y no de otra cosa). Me puedo traer sólo los id's la primera vez y luego "perezosamente" el resto, pero esto es peor aún, 3 querys para algo que puedo resolver en una sólo.

    Otra solución es que tengas un método en la persistencia de tipo "findDatosAdministrativosBy...." pero entonces estas proponiendo algo realmente muy similar a lo que yo estoy diciendo. La diferencia es que en tu caso subdivides la persona en trocitos que forman parte de tu modelo, es decir, haces que el problema ahora no este en persona sino en DatosAdministrativos, reduce el problema pero no lo resuelve.

    De hecho el enfoque que propones me parece totalmente correcto para diseñar un modelo, con esto me refería al principio con que la relación entre el modelo de objetos y relacional no es necesariamente 1:1, de una tabla "persona" pueden surgir n objetos en mi modelo DatosAdministrativos por ejemplo, y viceversa. Pero es que esto que propones ni es incompatible con lo que yo estoy diciendo ni resuelve el problema.

    Ahora me iden el dni y el nombre de mi padre en un listado, entonces tengo que cargar tanto los datos administrativos como los familiares y ya estoy cargando datos de más, ¿cuantos datos cargo de más?,¿es algo realmente importante desde el punto de vista del rendimiento?, pues dependerá de cuanto haya subdividido mi modelo y de lo que me diga un profiler y mis requisitos no funcionales.

    Si para un caso concreto la diferencia de rendimiento entre leer sólo lo que necesito y leer de más es significativa pues entonces no veo ningún problema en montarme un DTO que sólo contenga esos datos y utilizarlo.

    De la otra forma te ves obligado a crear un objeto virtual PersonaConDniEHijos (Para no traerte tropecientosmildatosinutiles), que nunca he tenido claro que es: Modelo o Vista, o ninguna de las dos?

    Pues si no esta claro a donde pertenece entonces es que no pertenece a ninguno de los dos, como dice cesar puedes tener un paquete dto donde incluir estas clases y nuestro karma de diseñador puede volver a respirar tranquilo xd. A veces me da la sensación de que nos encorsetamos demasiado con determinados patrones y los convertimos en pequeñas cárceles que no nos dejan diseñar tranquilamente. Que no se entienda esto mal, soy el primero que trata de seguir y aprender de todos los patrones y buenas practicas, pero en ocasiones hay soluciones sencillas y perfectamente validas que desechamos porque no encajan con lo que dice tal o cual patrón, "be water, my friend" xd.

  • remoh 04/01/2008 21:31

    ya que según esa idea la implementación del "modelo" debería saber en cada caso lo que necesita exactamente la vista.

    El módelo no tiene que saber nada, lo que ocurre es que la vista en algunos casos lo que presenta no es un objeto del módelo sino un DTO que no forma parte del módelo, sencillamente es un objeto de transferencia de datos, en ocasiones concretas el controlador/servicios lo que me devuelve no es un conjunto de objetos del módelo para que los presente sino que me devuelve un conjunto de DTO's. Sólo veo que se rompa la separación de conceptos porque la vista condiciona las querys que hago en la capa de persistencia, es decir, lo que quiero ver condiciona lo que le pido a la bd, pues me parece lógico y aceptable.

    Y claro esta que esto sólo es aceptable en casos donde por rendimiento merezca la pena, sino le mando "la persona" completa y listo. Como casi siempre es una situación donde tengo que llegar a un compromiso, en este caso entre rendimiento y diseño, esta claro que el módelo entero no esta en memoria y leerlo lleva asociado un coste, ni puedo ignorar este hecho ni puedo ignorar hacer una buena separación de conceptos en mi diseño, teniendo estas cosas en mente hay que buscar alguna solución de compromiso.

    De todos modos, que leer 3 campos de una bd para presentarlos en un listado de para tanta discusión es para plantearse si vamos por la dirección correcta en esto de la OO, los patrones etc,etc. ¿no os da a vosotros esa sensación? xd

  • greeneyed 04/01/2008 22:29

    El módelo no tiene que saber nada, lo que ocurre es que la vista en algunos casos lo que presenta no es un objeto del módelo sino un DTO que no forma parte del módelo, sencillamente es un objeto de transferencia de datos

    Quizá no he escogido la nomenclatura adecuada, con "modelo" no me refería unicamente a la parte de datos, si no a toda la parte que envía los datos a la vista, así que "modelo" no era la palabra correcta. Nosostros mismos no enviamos el modelo "tal cual" sino que a veces envías más o menos, pero sin llegar al extremo de envíar exactamente lo que necesitas.

    De todas formas creo que estamos de acuerdo en que la solución es un compromiso y ahí es donde entra lo "bueno" de discutir libremente alternativas, para tomar decisiones apropiadas (que no siempre son únicas) en base a información, sabiendo las alternativas, los pros y los contras etc.

    Y no creo que la discusión se aplique sólo a consultas de tres campos, para eso no hace falta ni OO ni XML ni leches en vinagre jejeje.

  • Anónimo 05/01/2008 16:53

    Hola de nuevo.

    A mi la discusión me ha gustado, no es que sea la más interesante de la historia de javaHispano, pero ha estado bien.

    Haceis tambien un gran apunte al subrayar que hay que usar el sentido comun por encima del patron o antipatron de turno. Aun así la literatura de patrones y antipatrones me gusta bastante, pero hay que saber leerla, no puedes tomartelo como una regla a aplicar si o si, sino como una experiencia de la que aprender.

    Sólo queria aclarar que la alternativa de hacer consultas de uno, dos o tres campos en vez de recoger todo el objeto del dominio deberia tenerse en cuenta por requisitos criticos de rendimiento. Por supuesto al rendimiento general de la aplicación le da igual que en un caso de uso se cojan 3 campos que 6 de BD, pero no 3000 que 6000.

    Un saludo.
    César.

  • ibon 05/01/2008 20:42

    A ver, yo parto de una opinión personal: los DTO's no me gustan y cuando los he usado me han parecido un artificio causado por un mal diseño mío. De hecho (lanzada a la piscina personal) para mí aparecieron como un problema derivado por los EJB's: tenemos una clase de modelo requetecagas que van a servir para hacer TOOODAS las aplicaciones que necesitemos en nuestra empresa, pero como carguemos el EJB entero, sólo nuestros nietos verán el resultado en pantalla. Así que nos montamos este "semi-modelo" para tener contenta a la vista. Así que parto de mi premisa personal ;-)

    Otra solución es que tengas un método en la persistencia de tipo "findDatosAdministrativosBy...." pero entonces estas proponiendo algo realmente muy similar a lo que yo estoy diciendo. La diferencia es que en tu caso subdivides la persona en trocitos que forman parte de tu modelo, es decir, haces que el problema ahora no este en persona sino en DatosAdministrativos, reduce el problema pero no lo resuelve.

    Siguiendo el porqué propongo eso (NO HACER USO DE DTO's), no es que reduzca el problema, sino que lo he resuelto: mi vista ahora muestra objetos de un modelo que TIENE SENTIDO. PersonaParaListadoFamiliar no tiene sentido ni porqué en ningún modelo, porque es una clase que aparece obligada por la existencia de determinada vista, no derivada de la lógica del negocio. DatosFamiliares además de servir para mostrarse en la vista, tendrá SENTIDO para otras cosas dentro del modelo.

    Ahora, que ya hemos pasado de la fase de diseño, pasemos a implementación ;-) ¿Que cuantas queries? Pues puede ser una o doscientas cuarenta ;-) ¿Una? Pues sí, si tu BD, CPU y ancho de banda te lo permiten, pues te cargas la persona con todos sos sus datos desde la BD... y DatosFamiliares te lo traes de la caché, por ejemplo. O es una query en la que para personas siempre se cargan sus DatosFamiliares (porque se usan mucho). O puede ser que se carguen sólo los datos administrativos... o ... inifinitas posibilidades :-D

    De hecho, si me lo permitís, este diseño te permitirá jugar mucho más si aparecen problemas de rendimiento sin "estropear" el diseño. Que si se usan mucho los DatosFamiliares se cachean cuando se hace otra consulta... o no, quien lo sabe. Si te fijas, el hecho de usar interfaces no era arbitrario. Yo hablaba de diseño, no de implementación.

    Si queréis mi discusión, era DTO's si o no. Osea PersonaDeLado, PersonaListado...etc (que comentaba Venkman). Y para mí son una solución cuando la he cagado realmente con el diseño.

    Salu2

    PD: Un posible escenario en el que los DTO's tienen sentido, estamos reusando modelo de otra aplicación distinta, o en el último momento nos piden un nuevo requerimiento. Pero de la nada, como vea un UML de diseño de un nuevo proyecto con PersonaListado.... ya me huele mal el asunto :-)

     

     

  • Anónimo 06/01/2008 20:08

    Jo... Si no he contestado más es porque me fui el fin de semana... Tsk... Si es que no hay como ir a pasárselo bien en la vida real para perder la posibilidad de pasártelo bien en la virtual xD

    Bueno, veamos... Ante todo reconozco que mi mensaje tenía algunas ambigüedades intencionadas. Y aclaro que, aunque más cerca de lo que dice Ibon, coincido con remoh en que generalmente prefiero ligarme por el sentido común (eso sí, un sentido común cultivado con buenas lecturas).

    Realmente escribí porque me parecía chocante que alguien (pero no es nada personal, supertorpe) estuviera hablando de "hilar más fino" en ¡ojo! el nivel (capa o lo que queráis) del acceso a datos o del ORM, y la forma de hacerlo fuera proponer crear una multitud de objetos que -a mi entender- no tienen la más mínima entidad propia como objetos del sistema.

    Quiero decir... si estamos hablando de un ORM y de "hilar más fino" que él, yo presupongo:

    • que hablamos del mapeado, de la relación entre los datos "puros" (en el almacén relacional) y los datos "con forma de objetos" (como objetos del modelo de nuestra aplicación).
    • que hablamos de una arquitectura -en general- bien estructurada. O al menos estructurada aceptablemente. i.e. la vista está separada del modelo y, desde luego, ni siquiera se imagina qué es lo que hay por debajo del modelo.

    Si no se da alguna de esos dos supuestos... apaga y vámonos, porque las discusiones sobre la elegancia de llevar un moco colgando frente a la de llevar una cagada de pájaro en el pelo, me parecen bastante absurdas.

    Si se dan, entonces entiendo que una propuesta que, desde la base de datos trae objetos que únicamente tienen sentido para una vista específica, me suena a meter SQL en el Javascript de una aplicación Web.

    Es decir, que estamos deshaciendo el modelo. Estamos saltándolo para que la vista acceda directamente (o casi) a unos datos particulares que sólo tienen sentido en esa vista pero no tienen entidad por sí mismos.

    De ahí que creo que la clave está en este comentario de Ibon: "...como vea un UML de diseño de un nuevo proyecto con PersonaListado...". Porque... ¿de qué estamos hablando de una buena arquitectura en la de planteemos alternativas (o diferentes opiniones) respecto a una capa determinada (la que ocupa el ORM de la discusión) o de si nos saltamos directamente la separación de capas y hacemos que el acceso a datos no se relacione con el modelo si no directamente con la vista?

     

    Y si de lo que habláis es de rendimiento y temas así, supongo que habréis tenido en cuenta al pensar estas cosas que SELECT * FROM PERSONAS WHERE persona_id = 1 es, en bastantes RDBMS tanto o más rápido que hacer SELECT nombre, apellidos, edad, dni, telefono, ciudad FROM PERSONAS WHERE persona_id = 1, ¿verdad?

     

    Bueno, siento no poder escribir más (ni más claro) ahora. Pero si queréis un resumen: Tampoco me gustan los DTOs y desde luego me gusta menos aún que los DTOs se usen para sustituir el modelo.

     

    -- Venkman 

  • Anónimo 06/01/2008 21:51

    Y si de lo que habláis es de rendimiento y temas así, supongo que habréis tenido en cuenta al pensar estas cosas que SELECT * FROM PERSONAS WHERE persona_id = 1 es, en bastantes RDBMS tanto o más rápido que hacer SELECT nombre, apellidos, edad, dni, telefono, ciudad FROM PERSONAS WHERE persona_id = 1, ¿verdad?

    Cuando hablaba de rendimiento no me referia a ese tipo de consultas, sino a la ganancia entre hacer:

    SELECT nombre, email FROM PERSONAS WHERE persona_id >1 AND persona_id <1000 (o directamente quitar el WHERE)

    en lugar de:

    SELECT * FROM PERSONAS WHERE persona_id >1 AND persona_id <1000

    Por supuesto, para el tipo de consultas que te refieres esta discusion es bastante esteril y usar DTOs seria un tanto estupido, salvo que el * incluya traerse un blob con una foto de la persona :)

    Un saludo.
    César.

  • Anónimo 07/01/2008 19:34

    De donde me bajo los demas podcast???

    Ssludos

  • JorgeRubira 07/01/2008 21:35

    Arriba tienes los links

    En el RSS puedes descargar los números anteriores.

  • Anónimo 08/07/2008 18:17

    Medio año despues veo esta discusion, y me hubiera gustado mucho participar.

    no se si alguien que participo me pueda contestar, pàra ver si mi diseño esta bien o mal.

    Mas alla del ORM yo creo objetos que son el modelo de mi dominio (POJOS), pero cuando necesito hacer vistas es decir consultas, sobre una entidad (algun subconjunto o super conjunto de datos de personas, es decir datos de personas parciales en una tabla, o puede ser datos de personas+mas columnas adicionales de otra tabalas relacionadas con join) entonces uso Beans dinamicos basados en un mapa (campo,valor) donde siempre el primer campo es el id de la entidad en cuestion (Persona).

    Asi la capa de vista accede solo a estos beans dinamicos, y si quieren hacer algun proceso con los datos, pueden hacerlo enviando el id del objeto seleccionado.

    Ahora la unica vez en que la vista toca el modelo, es cuando necesito crear una entidad, ahi a final la vista siempre construye un objeto entidad de mi Modelo  (Persona por ejemplo) y lo manada a la capa del modelo para insercion o validacion.

    Asi en mi modelo use o no un ORM cuando cargo un objeto de entidad lo cargo completo, pero cuando creo un objeto para una vista,tabla o lista,uso los Beans dinamicos.

     Que les parece hago bien o creenq ue he errado algo. ahora como llegue a esta discusion fue buscando como usar JPA con aplicaciones desktop , y me quede con la discusion que se armoa aqui.

    Alguien sabe si es buena idea mezclar ambas, desktop y jpa, con cualquiera de su proveedores, Hibernate, TopLink etc

     

    Arturo

Escribe tu comentario

Sun Microsystem Logo NHT-Norwick Logo

© 2002-2007 Asociación javaHispano