[artesanos-de-software] Duda objetos en listado

25 views
Skip to first unread message

Jesus Jimenez

unread,
Sep 29, 2010, 5:48:21 AM9/29/10
to artesanos-...@googlegroups.com
Hola,

Me gustaría saber cómo afrontais vosotros un "problema" que me encuentro bastante habitualmente en las aplicaciones que tengo que hacer. Voy a tratar de poner un ejemplo:

Mi aplicación se basa por ejemplo en trabajar con solicitudes. Estas solicitudes aparte de información propia de la solicitud (id, descripción, fecha de creación y campos similares), está creada por un usuario, pertenece a un "tipo de solicitud" y tiene documentos anexados por ejemplo. Esto a simple vista parece que hay una relación 1-N en la BD de solicitud con las tablas de usuarios, tipo de solicitud y documentos y cada uno con sus campos.

Ahora resulta que quiero mostrar un listado como el siguiente:

Fecha_Solicitud | Descripcion_solicitud | Tipo_Solicitud | Usuario_Creacion | Nombres_Documentos

El resto de campos de todos los objetos no los necesito para nada.

Lo que me viene a la mente a priori son 2 posibilidades:
1) la parte de presentación pide un listado de objetos "solicitud" rellenas con cada uno de los otros objetos y luego las recorra cogiendo los campos que necesita de cada objeto e ignorar los demás
2) pide un listado de objetos que sólo tengan los campos que necesito para el listado, ni más ni menos.

Veo algún inconveniente y ventaja de cada una de las posibilidades:
1) Objetos mucho más estandar para el resto de la aplicación, muy reutilizables, pero tengo objetos más grandes y con más datos de los que necesito yendo y viniendo
2) Mucho menos reutilizable cada objeto (puedo tener más listados, pero no tienen todos los mismos campos exáctamente) y en caso de cambios en el listado me cambia el bean, pero sólo tengo un objeto con lo que necesito. Además, no tengo muy claro como llamar a este objeto. Por otro lado, no se quien tendría que rellenar este objeto, el dao directamente? la clase de negocio? en presentación?

Alguna idea? Hay una 3ª opción que no contemplo?

Gracias por adelantado!
Jesús Jiménez

Alfredo Casado

unread,
Sep 29, 2010, 6:46:33 AM9/29/10
to artesanos-...@googlegroups.com
pues no se, voy a escribir un test (funcional) a ver que me sale:

me invento que el listado se genera entre una fecha de inicio y una de fin, por ejemplo:

@Test
public void debeSerCapazDeGenerarUnLIstadoDeSolicitudesEntreUnaFechaDeInicioYUnaDeFin() {

        // introducir los datos de listado, con un builder o un object mother o lo que sea, esto me lo salto.

       InformeSolicitudes informe = new GeneradorInformeSolicitudes().conFechaInicio(...)
                                                                                                   .conFechaFin(...)
                                                                                                   .construirListado();

       assertThat(informe.numeroRegistros(), is(1)); // sólo pongo un registro entre los datos de pruebas porque pruebo el caso más simple
       assertThat(informe, tieneRegistroCon(fechasolicitud,descripcion,.......,));
}

Dentro del matcher que genere "tieneRegistroCon" verifico si la linea del informe es como debe ser, para eso el objeto informe implementa por ejemplo la interfaz Iterable y me va devolviendo objetos del tipo LineaDeInformeSolicitud que sólo tienen los campos necesarios para el informe.

A mi con ese requisito me salen más o menos estas clases. Si te da por intentar reutilizar (más bien forzar) las otras clases de modelo que tienes para cubrir este requisito te estas perdiendo modelar toda la parte de informes, que si es importante en tu aplicación merece disponer de sus propias clases para modelar sus reglas. Fíjate que luego los informes y los generadores de informes podrían cumplir con alguna interfaz y quizás después de hacer unos cuantos informes de este modo se te ocurre como generalizar mucho mejor la parte de los informes. 

Eduardo Ferrández

unread,
Sep 29, 2010, 7:30:41 AM9/29/10
to artesanos-...@googlegroups.com
La respuesta de Alfredo está muy bien, pero disiento respecto a crear un tipo LineaDeInformeSolicitud, ya que por lo que dice Jesús, si son meros contenedores de información (recupero el dato para luego presentarlo) no aportan nada al negocio y pueden ensuciarlo. Yo utilizaría objetos dinámicos o mapas. Además el test te sigue valiendo ;)

Jesus Jimenez

unread,
Sep 29, 2010, 7:49:41 AM9/29/10
to artesanos-...@googlegroups.com
Muchas gracias por las respuestas!

Me gusta la forma que indicas Alfredo, voy a mirarlo. De todas formas, centro un poco más el "problema". Esto realmente no es para informes (aunque eso da igual), sino más bien que se muestra un listado de estas solicitudes para poder hacer un CRUD.
El caso es que, dependiendo del perfil que acceda, verá unos campos u otros, es decir, si yo con mi rol solicitante no tiene sentido que vea en mi listado que yo soy el creador de todas las solicitudes, ya que sólo puedo ver las mías. Por otro lado, si entra el rol "jefe_de_todo", sí que debería poder ver quién es el creador de esa solicitud.
Por lo tanto, debería de crear un test debeSerCapazDeGenerarUnLIstadoDeSolicitudesEntreUnaFechaDeInicioYUnaDeFinSolicitante y un debeSerCapazDeGenerarUnLIstadoDeSolicitudesEntreUnaFechaDeInicioYUnaDeFinJefazo teniendo en común InformeSolicitudes?o debería de tener InformeSolicitudeSolicitante e InformeSolicitudesJefazo?

Eduardo, dices que en vez de crear un objeto con una línea del listado, hacerlo con un mapa? Yo personalmente trato de usar lo menos posibles estos objetos aunque yo creo que es por un trauma infantil de unos de mis primeros proyectos donde todos los parámetros de entrada y el resultado de salida de las funciones eran maps y era un infierno total. Eso sí, todos nuestros métodos tenían como mucho un parámetro de entrada.

Xavi Gost

unread,
Sep 29, 2010, 5:54:57 AM9/29/10
to artesanos-...@googlegroups.com
Mi recomendación es que a la vista solo viajen los datos que van a ser
presentados, es más lo ideal es que el dominio recupere solo los datos
que va a mandar a la vista.
y sobre todo que viajen DTO's no objetos de dominio.

En tu caso, seria el dominio el que recogería del DAO los datos de las
diferentes entidades y compondría el DTO

xavi

2010/9/29 Jesus Jimenez <yey...@gmail.com>:

Alfredo Casado

unread,
Sep 29, 2010, 9:48:58 AM9/29/10
to artesanos-...@googlegroups.com
Eduardo, lo de la clase LineaDeInformeSolicitud es un poco por que luego lo voy a enviar a un jsp (o similar tecnología de vista) y va a ser más cómodo teniendo una clase que teniendo simplemente un mapa o similar. Como más que una clase es una mera estructura de datos podría valer con que tuviera todas las propiedades publicas y listo (no pasa nada, si son estructuras de datos), el problema es la dichosa manía de los beans de java y de los frameworks que sólo funcionan con beans. Pero es un poco en la linea de lo que dice xavi, a la vista que sólo le llegue lo que tiene que representar.

Sobre lo de filtrar distintos campos para distintos usuarios, al construir el informe haría algo como:

 InformeSolicitudes informe = new GeneradorInformeSolicitudes().conFechaInicio(...)
                                                                                              .conFechaFin(...)
                                                                                              .paraUsuariosConElRol(JEFAZO)
                                                                                              .construirListado();

El informe de solicitudes sigue siendo una única cosa, simplemente luego ese informe en función de el rol devuelve las lineas de una manera u otra. Puedes usar herencia y tener una lineaGenerica y que hereden las lineas que añadan más información para el jefazo, puedes hacerlo más simple y devolver un mapa como decía eduardo, en función de la tecnología de vista que uses habría que ver como queda más apañao. 

Pero en el fondo tanto el informeSolicitudes como las lineas son meros contenedores de información, me preocupa menos esa parte, lo que si es importante es que el generador de informes, que es el que tiene la lógica complicada de saber como tiene que componer los informes en función de roles y otros filtros forme parte de tu dominio y sea testable, que no este metida la lógica de recorrer los objetos de dominio en un controlador o cosas así.

Eduardo Ferrández

unread,
Sep 29, 2010, 10:27:01 AM9/29/10
to artesanos-...@googlegroups.com
Alfredo y Xavi, totalmente de acuerdo con lo de enviar sólo los datos que se van a mostrar en la vista. Por otro lado sí que es cierto que los frameworks java tienden a obligarte a declarar beans, pero por ejemplo EL (jsp, faces) te permite acceder a las propiedades de mapas como si fuesen beans. Si vas a serializar a json o xml también suele ser indiferente usar un mapa o un objeto. Si puedo elegir, prefiero no tener que declarar un bean sólo para transferir entre persistencia y presentación.

Jesús: una cosa es usar un mapa para transferir datos del modelo a la vista sin tener que manipularlos y otra cosa es usar mapas para implementar la lógica de negocio. ¿Para qué voy a llenar mi código de getters y setters a los que nunca voy a hacer referencia porque ya lo hace mi framework? No sólo dificultan la lectura: si quiero usar alguna herramienta para detectar código no referenciado, esos getters y setters van a dar "falsos positivos".

En resumen: si la tecnología que usas lo permite, usa mapas para transferir sólo si no vas a hacer referencia a sus propiedades en la lógica.

Abel Cuenca

unread,
Sep 29, 2010, 8:53:57 AM9/29/10
to artesanos-...@googlegroups.com
Buenas,

Estoy totalmente de acuerdo con Xavi en lo de separar datos de dominio y datos de presentacion. De hecho cuando he leído el correo inicial he pensado en CQRS, que dice aquello de separar tus Reports de tus Commands. En internet hay tropocientas introducciones al tema, por coger la primera que me da google: http://blog.fossmo.net/post/Command-and-Query-Responsibility-Segregation-%28CQRS%29.aspx.

Para el tema de InformeSolicitudes y si usar una común o varias especificas en función del rol, no me queda claro si el requisito es que hay campos que ciertos usuarios no ven, o que hay ciertas solicitudes que algunos usuarios no ven. ¿puedes clarificarlo?

Un saludo,
Abel.



2010/9/29 Xavi Gost <xav...@gmail.com>

Alfredo Casado

unread,
Sep 29, 2010, 10:58:55 AM9/29/10
to artesanos-...@googlegroups.com
[...] Para el tema de InformeSolicitudes [...]

jeje, en cuanto se pone un poquito de código (sobre todo un test) se va creando un ubiquitous language, ya en este mismo correo hablamos en el lenguaje del dominio :P

ni caso, que me estoy leyendo DDD y se me va la cabeza.

Jesus Jimenez

unread,
Sep 29, 2010, 11:11:46 AM9/29/10
to artesanos-...@googlegroups.com
El 29 de septiembre de 2010 14:53, Abel Cuenca <abel....@gmail.com> escribió:

Para el tema de InformeSolicitudes y si usar una común o varias especificas en función del rol, no me queda claro si el requisito es que hay campos que ciertos usuarios no ven, o que hay ciertas solicitudes que algunos usuarios no ven. ¿puedes clarificarlo?

La idea es que depende del rol le pueda interesar uno u otro campo que se visualice. Por ejemplo, si yo he creado la solicitud, como dije antes, no me interesará ver en mi listado el usuario creador porque seré yo mismo siempre, pero en el caso de mi jefe, que verá mis solicitudes y las de otros más como yo, sí que necesitaría ver de quién es cada una.

Voy tomando nota de todo lo que decís... no he sido más concreto con la tecnología en concreto porque mi idea era ver las ideas que se puedan adaptar más o menos a todo, aunque luego se adaptará mejor a cada caso una forma u otra. En este caso en concreto estoy con Struts 1.3 (que ya tiene la mili hecha y todo...) + Spring 2.5 + JDBC (usando las plantillas que me da Spring).
La arquitectura no me convence absolutamente nada, por eso de ir cambiando poco a poco a algo mejor (o esa es mi idea, ya mejoré algo pudiendo meterle pruebas unitarias y de integración después de alguna pregunta en el grupo de tdd-es). Ahora mismo un flujo "normal" sería:

Action de Struts que pide las solicitudes -> Servicio que recibe la peticion y la redirige al DAO (sin o ninguna mucha lógica)-> Clase con acceso a la BD que realiza las consultas y monta un bean -> Vuelve al servicio que transforma el bean que le llega del DAO al Bean que entiende el Action de Struts -> Action de Struts de nuevo -> JSP.

(Espero no haber liado más todo...)

Gracias!!

jcesarperez

unread,
Sep 29, 2010, 11:27:18 AM9/29/10
to Artesanos de Software
Hola a todos.

¿Cuando usáis "enviar" os referís a enviar realmente el objeto al
navegador cliente, tipo servicios rest con json? Supongo que sí, pero
por dejarlo claro, ya que si usamos una tecnología tipo jsp, los datos
no viajan al cliente, solo viaja el html construido. Es decir, puedes
recoger 20 datos que si sólo pintas 2, sólo se "envian" 2. Por tanto
ese exceso de datos sólo te penaliza en memoria de servidor y el ancho
de banda entre el servidor de aplicaciones y la bdd.

Entonces si es el 1er caso nosotros también solemos crear
practicamente una clase por cada cosa que pinto en pantalla y las
metemos en un paquete dto separado del modelo. Si es el 2o caso, sólo
creamos nuevas clases para los casos donde la penalización es
significativa.

Un saludo.
Julio.

On 29 sep, 16:58, Alfredo Casado <casado.alfr...@gmail.com> wrote:
> *[...] Para el tema de InformeSolicitudes [...]*
> *
> *
> jeje, en cuanto se pone un poquito de código (sobre todo un test) se va
> creando un ubiquitous language, ya en este mismo correo hablamos en el
> lenguaje del dominio :P
>
> ni caso, que me estoy leyendo DDD y se me va la cabeza.
> *
> *
> El 29 de septiembre de 2010 14:53, Abel Cuenca <abel.cue...@gmail.com>escribió:
>
> > Buenas,
>
> > Estoy totalmente de acuerdo con Xavi en lo de separar datos de dominio y
> > datos de presentacion. De hecho cuando he leído el correo inicial he pensado
> > en CQRS, que dice aquello de separar tus Reports de tus Commands. En
> > internet hay tropocientas introducciones al tema, por coger la primera que
> > me da google:
> >http://blog.fossmo.net/post/Command-and-Query-Responsibility-Segregat...
> > .
>
> > Para el tema de InformeSolicitudes y si usar una común o varias especificas
> > en función del rol, no me queda claro si el requisito es que hay campos que
> > ciertos usuarios no ven, o que hay ciertas solicitudes que algunos usuarios
> > no ven. ¿puedes clarificarlo?
>
> > Un saludo,
> > Abel.
>
> > 2010/9/29 Xavi Gost <xavi...@gmail.com>
>
> > Mi recomendación es que a la vista solo viajen los datos que van a ser
> >> presentados, es más lo ideal es que el dominio recupere solo los datos
> >> que va a mandar a la vista.
> >> y sobre todo que viajen DTO's no objetos de dominio.
>
> >> En tu caso, seria el dominio el que recogería del DAO los datos de las
> >> diferentes entidades y compondría el DTO
>
> >> xavi
>
> >> 2010/9/29 Jesus Jimenez <yeyu...@gmail.com>:

Xavi Gost

unread,
Sep 29, 2010, 12:06:17 PM9/29/10
to artesanos-...@googlegroups.com
> ¿Cuando usáis "enviar" os referís a enviar realmente el objeto al
> navegador cliente, tipo servicios rest con json? Supongo que sí, pero ....{SNIP}

Yo me refiero a los dos casos, no es una cuestión de profiling es una
cuestión de corrección y separación de responsabilidades

> Entonces si es el 1er caso nosotros también solemos crear
> practicamente una clase por cada cosa que pinto en pantalla y las
> metemos en un paquete dto separado del modelo. Si es el 2o caso, sólo
> creamos nuevas clases para los casos donde la penalización es
> significativa.

Vaya mi recomendación es hazlo siempre independiente de la
arquitectura de despliegue... en los proyectos que hago considero
Vista Controlador y Dominio como artefactos independientes y muchas
veces cada uno esta construido con diferente tecnología.

jcesarperez

unread,
Sep 29, 2010, 1:43:38 PM9/29/10
to Artesanos de Software
Entonces digamos que tienes una tabla Usuario con login, apellido1,
apellido2, nombre, dni, correo, activo, fecha_creacion (legacy db
schema). Obviamente tendrás tu entidad Usuario correspondiente con los
mismos atributos que columnas en la tabla. Y ahora llegan y te piden
una jsp para listar los logins + correo de los usuarios activos.
¿Creas una nueva clase LoginMasCorreoUsuario o llamala X? ¿Y si mañana
te piden otro listado diferente con apellidos, nombre y correo creas
otra nueva clase Z?

Eduardo Ferrández

unread,
Sep 29, 2010, 1:46:17 PM9/29/10
to artesanos-...@googlegroups.com
Por eso decía yo lo de los mapas, para no llenar la aplicación con objetos que no tienen ningún sentido para el negocio y que son menos transmisores;)

Eduardo Ferrández

unread,
Sep 29, 2010, 1:52:06 PM9/29/10
to artesanos-...@googlegroups.com
Fe de erratas: y que son meros transmisores

Xavi Gost

unread,
Sep 29, 2010, 2:12:05 PM9/29/10
to artesanos-...@googlegroups.com
> Entonces digamos que tienes una tabla Usuario con login, apellido1,
> apellido2, nombre, dni, correo, activo, fecha_creacion (legacy db
> schema). Obviamente tendrás tu entidad Usuario correspondiente con los
> mismos atributos que columnas en la tabla.

No tan obvio, un objeto de dominio no tiene que ir mapeado a una sola
tabla,,, pero eso es harina de otro costal


> una jsp para listar los logins + correo de los usuarios activos.
> ¿Creas una nueva clase LoginMasCorreoUsuario o llamala X? ¿Y si mañana
> te piden otro listado diferente con apellidos, nombre y correo creas
> otra nueva clase Z?

Es una cuestión de karma, no de dogma, sabemos por que lo hacemos.
Si nos piden un dato mas y es coherente ponerlo en el primer DTO pues
lo ponemos aunque no se usen todos los datos en cada uso. Si no tiene
coherencia o es un bunch diferente de datos aunque vengan del mismo
objeto de dominio pues se hace un nuevo DTO

Que problema hay en crear clases nuevas? se ponen en su paquete de
DTO's y a volar!!

Eduardo Ferrández

unread,
Sep 29, 2010, 2:54:18 PM9/29/10
to artesanos-...@googlegroups.com



Que problema hay en crear clases nuevas? se ponen en su paquete de
DTO's y a volar!!

Que generas un montón de getters y setters que sólo van a ser usados por el framework correspondiente, que van a ser falsos positivos cuando busques código no usado y código duplicado. Además requieren un mantenimiento cuando cambiamos la vista o los datos a extraer. En resumen, generan ruido. Si son 3 vale. Si son 100 tienes un problema.

jcesarperez

unread,
Sep 29, 2010, 3:45:59 PM9/29/10
to Artesanos de Software
> Es una cuestión de karma, no de dogma, sabemos por que lo hacemos.

Que conste que sólo quiero comprender tu punto de vista. Entiendo que
lo que sí es tu dogma es no usar las clases del modelo en la vista.
Eso es lo que antes has llamado una cuestión de corrección y
separación de responsabilidades. No es que me parezca mal, pero yo me
siento un poco incomodo teniendo la clase del modelo Usuario y luego
la clase dto UsuarioDto . Por eso sólo creo clases dto cuando las del
modelo me son ineficientes, o bien porque sólo necesitas un par de
atributos de una clase enorme o bien porque necesitas algunos
atributos que están repartidos entre varias clases.

Por cierto, ¿usas DDD?

Y otra pregunta: ¿para el típico a.setX(b.getX()) usas las beansutils
u otra librería o los haceis a pelo?

Un saludo.
Julio.

Alfredo Casado

unread,
Sep 29, 2010, 7:14:30 PM9/29/10
to artesanos-...@googlegroups.com
Que la vista trate directamente con las clases del modelo puede traer problemas, no tiene porque estar mal conste, si resuelve tu problema y el resultado es mantenible prueba superada, pero con cuidadin.

Por ejemplo, no hay excepción más famosa en el mundo que la "lazyInitializationException" de hibernate, esta excepción que seguro que conocéis siempre pasa porque desde la vista intentas navegar por tus objetos de dominio cuando la conexión a bd esta cerrada, ejemplo típico alumno.getAsignaturas() en la vista. Para eso se han inventado guarradas tan tremendas como el "open session in view" que tienen la jeta de llamarlo patrón, chapuza consistente en cerrar la conexión después de procesar el jsp, en un servlet filter, para que si a la vista le da por hacer guarreridas no salte la famosa excepción.

Tener clases dto que más que clases son simples estructuras de datos, te obliga a pensar y hacer explicito en tu código que necesita la vista, de esta manera evitas problemas como el de antes, aunque es más trabajoso y puede no merecer la pena en todos los casos, eso es lo bonito de esto, que todo depende y no hay reglas absolutas.

 ¿para el típico a.setX(b.getX()) usas las beansutils u otra librería o los haceis a pelo?

Hay cosas como http://dozer.sourceforge.net/ más potentes que beanutils para estos menesteres, pero la use una vez y no me gusto demasiado. 

lo que no me gusta es que un dto tenga sets ¿para que?, son objetos de transportes de datos, ¿cual es el problema con declarar todas las propiedades publicas?, si son objetos sin lógica no son objetos son estructuras de datos y no necesito métodos de acceso. y para crearlos, sobre todo si son gordotes, un builder queda muy bonito:

Usuario user = .....

return aUserForView().withFirstName(user.getFirstName())
                                .withLastName(...)
                                .withEsto(...)
                                .withAquello(...)
                                .build();

Estas clases (no me gusta lo de dto) son parte de la vista no del dominio, simples utilidades para marcar la separación entre vista y modelo y definir mejor el contrato entre estas dos capas. Como digo, en casos simples lo mismo es pasarse, depende.

Gonzalo Garcia

unread,
Sep 30, 2010, 2:18:40 AM9/30/10
to artesanos-...@googlegroups.com
El 30/09/2010 1:14, Alfredo Casado escribi�:

> Que la vista trate directamente con las clases del modelo puede traer
> problemas, no tiene porque estar mal conste, si resuelve tu problema y
> el resultado es mantenible prueba superada, pero con cuidadin.
>
> Por ejemplo, no hay excepci�n m�s famosa en el mundo que la
> "lazyInitializationException" de hibernate,
A mi, desde mi absoluta inocencia ignorante, me parece que no es una
buena pol�tica supeditar una decisi�n de arquitectura a un
comportamiento concreto de una librer�a concreta. M�s si hablamos de la
arquitectura de una parte y una librer�a que trabaja en otra parte
diferente. Pero, como digo, esto lo pienso desde un punto de vista muy
inocente.

Jesus Jimenez

unread,
Sep 30, 2010, 3:48:29 AM9/30/10
to artesanos-...@googlegroups.com
El 30 de septiembre de 2010 01:14, Alfredo Casado <casado....@gmail.com> escribió:
lo que no me gusta es que un dto tenga sets ¿para que?, son objetos de transportes de datos, ¿cual es el problema con declarar todas las propiedades publicas?, si son objetos sin lógica no son objetos son estructuras de datos y no necesito métodos de acceso.

Al final te convenció el tío Bob? si no recuerdo mal, escribiste un post en el blog sobre el Clean Code donde decías que no estabas muy convencido sobre eso de poner las propiedades como públicas... ;)

Lo que comentas del problema de trabajar con las clases del modelo no es algo que a mi tampoco me convenza, por eso he tratado de hacer "conversores" a beans con los que trabaje la presentación pero no me ha terminado de gustar nada.
En mi caso concreto, al estar trabajando con JDBC sin ningún framework que me obligue a crear beans del modelo, creo que voy a tirar por rellenar directamente los DTOs con el resultado de la consulta y subir eso para arriba para que lo interprete la vista.

Alfredo Casado

unread,
Sep 30, 2010, 5:35:14 AM9/30/10
to artesanos-...@googlegroups.com
Gonzalo: lo de hibernate es un ejemplo, no es que te condiciones por hibernate (yo no lo uso) es que desde la vista estas llamando a un método del modelo que a su vez provoca una llamada a la base de datos, esto en general me parece problemático, es preferible que a la vista le pases los datos preparados. Pero de todos modos, los frameworks/tecnologías que uses claro que condicionan tu arquitectura, y mucho, el diseño y la implementacion son dos caras de la misma moneda, no puedes diseñar sin tener en cuenta los problemas de implementacion ni usar una implementación o framework sin tener en cuenta su impacto en la arquitectura.

Jesus: jeje, pues cada vez estoy más convencido, que parece que si pones una propiedad publica te va a caer un rayo fulminador del cielo, pero no, de momento no me ha caído ninguno jeje.

jcesarperez

unread,
Sep 30, 2010, 6:20:12 AM9/30/10
to Artesanos de Software
Totalmente de acuerdo en todo. Está claro que dividir completamente
las clases de la vista (dto) y las clases del modelo es una propuesta
muy ordenada que tiene sus ventajas e inconvenientes. Ya dependerá del
contexto y necesidades de cada proyecto.

Lo único que no me gusta es lo de sustituir los sets de los dto por
builders. No es que no me gusten los builders, pero prefiero usarlos
para objetos de más calado y lo de los dtos solucionarlo metiendo
todos los set(get) en un método auxiliar en plan buildUserDto(user).

Un saludo.
Julio.

On 30 sep, 01:14, Alfredo Casado <casado.alfr...@gmail.com> wrote:
> Que la vista trate directamente con las clases del modelo puede traer
> problemas, no tiene porque estar mal conste, si resuelve tu problema y el
> resultado es mantenible prueba superada, pero con cuidadin.
>
> Por ejemplo, no hay excepción más famosa en el mundo que la
> "lazyInitializationException" de hibernate, esta excepción que seguro que
> conocéis siempre pasa porque desde la vista intentas navegar por tus objetos
> de dominio cuando la conexión a bd esta cerrada, ejemplo típico
> alumno.getAsignaturas() en la vista. Para eso se han inventado guarradas tan
> tremendas como el "open session in view" que tienen la jeta de llamarlo
> patrón, chapuza consistente en cerrar la conexión después de procesar el
> jsp, en un servlet filter, para que si a la vista le da por hacer
> guarreridas no salte la famosa excepción.
>
> Tener clases dto que más que clases son simples estructuras de datos, te
> obliga a pensar y hacer explicito en tu código que necesita la vista, de
> esta manera evitas problemas como el de antes, aunque es más trabajoso y
> puede no merecer la pena en todos los casos, eso es lo bonito de esto, que
> todo depende y no hay reglas absolutas.
>
> * **¿para el típico a.setX(b.getX()) usas las beansutils u otra librería o
> los haceis a pelo?*
> *
> *
> *Hay cosas comohttp://dozer.sourceforge.net/más potentes que beanutils
> para estos menesteres, pero la use una vez y no me gusto demasiado. *
> *
> *
> *lo que no me gusta es que un dto tenga sets ¿para que?, son objetos de
> transportes de datos, ¿cual es el problema con declarar todas las
> propiedades publicas?, si son objetos sin lógica no son objetos son
> estructuras de datos y no necesito métodos de acceso. y para crearlos, sobre
> todo si son gordotes, un builder queda muy bonito:*
> *
> *
> *Usuario user = .....*
> *
> *
> *return aUserForView().withFirstName(user.getFirstName())*
> *                                .withLastName(...)*
> *                                .withEsto(...)*
> *                                .withAquello(...)*
> *                                .build();*
> *
> *
> *Estas clases (no me gusta lo de dto) son parte de la vista no del dominio,
> simples utilidades para marcar la separación entre vista y modelo y definir
> mejor el contrato entre estas dos capas. Como digo, en casos simples lo
> mismo es pasarse, depende.
> *
>
> El 29 de septiembre de 2010 21:45, jcesarperez <
> julio.cesar.perez.arq...@gmail.com> escribió:

Gonzalo Garcia

unread,
Sep 30, 2010, 6:33:52 AM9/30/10
to artesanos-...@googlegroups.com
El 30/09/2010 11:35, Alfredo Casado escribi�:

> Gonzalo: lo de hibernate es un ejemplo, no es que te condiciones por
> hibernate (yo no lo uso) es que desde la vista estas llamando a un
> m�todo del modelo que a su vez provoca una llamada a la base de datos,
> esto en general me parece problem�tico, es preferible que a la vista

> le pases los datos preparados.
Bueno, tampoco es que haya defendido pasar objetos del modelo
directamente a la vista.

Sin embargo, lo que dices tampoco tiene por qu� ser as�.
> desde la vista estas llamando a un m�todo del modelo que a su vez


> provoca una llamada a la base de datos

No, no necesariamente. Porque ah� est�s asumiendo una situaci�n muy
concreta. Es decir, el modelo no tiene por qu� provocar ninguna llamada
a la base de datos. S�lo ocurre en la situaci�n en la que as� has
planteado tu arquitectura. Es decir, no, no digo que no *pueda* ser
problem�tico. Lo �nico que estoy diciendo es que la bondad de esa
decisi�n la est�s ligando a otras elecciones de implementaci�n. Esto no
tiene por qu� ser malo, insisto, pero desde luego no es aplicable de
forma general. S�lo cuando se tomen esas mismas elecciones.

Dicho en otras palabras, que est�s haciendo que el que la elecci�n de
usar DTOs para pasarlos a la vista sea buena idea o no, dependa de otras
elecciones que has hecho en otras capas (entre el modelo y la
persistencia). (Sea Hibernate o sea lo que sea si se comporta
similarmente en ese aspecto)

gnz/vnk

GermanDZ

unread,
Oct 12, 2010, 4:32:23 PM10/12/10
to Artesanos de Software
Algo que alguna vez he leído por ahí y no he puesto en práctica,
aunque parecía interesante:
Cuando se da el caso que partiendo de un mismo objeto de dominio que
digamos es "grandecito" (que tiene muchos atributos) tenemos la
necesidad de realizar múltiples presentaciones del mismo pero
mostrando distintos subconjuntos de sus atributos se puede hacer lo
siguiente:

El DTO de presentación contiene todos los atributos, pero se le
adiciona un "esquema" o "configuración" que permite saber cuales de
esos atributos contienen valores significativos (si tenemos nil creo
que tema solucionado). Entonces las vistas pueden compartir el DTO y
basarse en ese esquema para saber que presentar y que no. Esto tiene
sentido por ejemplo si la presentación gráfica se (auto)genera por
introspección o algo así.

Al servicio que nos provee la información no le interesa esto y por lo
tanto que aislado del problema de presentación y sus test siguen
siendo siempre los mismos a pesar de cambios en lo que voy a
presentar.

José Manuel Beas

unread,
Oct 12, 2010, 5:41:09 PM10/12/10
to artesanos-...@googlegroups.com
No tengo muy claro si esto que cuentas, Germán, tiene que ver con esto otro: http://www.nakedobjects.org

BTW, ¿alguien tiene en la lista experiencia con esto? Siempre he querido probarlo pero nunca ha estado lo suficientemente arriba en mis prioridades. :(

German DZ

unread,
Oct 12, 2010, 6:27:44 PM10/12/10
to artesanos-...@googlegroups.com
Lo estuve leyendo y no, naked objects tiene un enfoque de "inferir la presentación en base al dominio" eso no me gusta... para que tener 4 capas (como dicen ahí) si luego te pasas la vida buscando como evitarlas.

Lo que yo digo va más de:

Dominio:
libro={isbn, autor, titulo, tema, resumen, cantidadPagina, encuadernacion, editorial, fechaPublicacion, etc1, etc2, etc3}
UI:
Listado de libro por tema
libroUI.esquema={isbn, autor, editorial}
Detalle del libro
libroUI.esquema={isbn, autor, titulo, tema, resumen, cantidadPagina, encuadernacion, editorial, fechaPublicacion}

Servicios:
libroUI* buscarLibros(criterios, esquema)

Entonces le indicas al servicio cual es el "esquema" que esperas encontrar en la respuesta

Algo así.. no es la forma más limpia de lograrlo ya que se pierde algo de semántica en los servicios, pero se puede llevar esto a un patrón (seguramente alguien ya se lo atribuyó).

2010/10/12 José Manuel Beas <jose....@gmail.com>

yeraycaballero

unread,
Oct 17, 2010, 6:27:56 PM10/17/10
to Artesanos de Software
Hola Jesus,

Yo entiendo que lo que necesitas son distintas estrategías para
recuperar los datos de los listados. Así podrías aplicar una
"estrategía de búsqueda" para cada rol que tengas en la aplicación.

De las dos opciones que comentas yo me quedo con la segunda. No tiene
sentido cargar todos los objetos y sus relaciones si luego no se van a
mostrar en el listado. Lo ideal sería esperar sólo lo justo y
necesario.

Yo veo la solución de la sigiuente manera: lo que queremos mostrar al
usuario son solicitudes.
Para ello, bastaría con pedirseló al repositorio de solicitudes, el
cual devolvería objetos en función de la estrategía de búsqueda que
aplique dada una especificación

Cada estrategía devolvería una lista de objetos order cargados
parcialmente con los datos
que se vayan a mostrar a cada rol.

List<Order> OrdersRepository.getOrders(spec) {
FetchingStrategy strategy =
fechingStrategyFactory.getStrategy(spec)
return strategy.fetch();
}

Cada estrategía a su vez puede pedir al ORM que cargue los objetos
aplicando la estrategía de búsqueda que considere oportuna:
(eagerLoading, lazyLoading, etc.)

List<Order> order = ordersRepository.getOrders(new Spec(Roles.ADMIN));
List<Order> order = ordersRepository.getOrders(new Spec(Roles.USER));

Y si antes de enviar al cliente el objeto podrías adaptarlo a un DTO.

A lo mejor te vale. un saludo y gracias por la consulta

Yeray Caballero
Reply all
Reply to author
Forward
Message has been deleted
0 new messages