[artesanos-de-software] Control de la existencia y/o contenido de muchos campos

52 views
Skip to first unread message

Kinisoftware

unread,
Oct 27, 2010, 12:00:18 PM10/27/10
to Artesanos de Software
Buenas a tod@s,

hoy me he vuelto a encontrar con un caso, recurrente creo yo, en
muchas aplicaciones. La validación de campos de forma masiva, es
decir, para una estructura llena de atributos saber si vienen a null
y, en algunos casos, si están vacios como por ejemplo una cadena "".
Aunque uso Java busco un patrón, una estrategia, una forma elegante y
legible de resolverlo, independiente del lenguaje.

Quizás no he pensado lo suficiente o me faltan las herramientas
adecuadas porque lo primero que siempre me viene a la cabeza es la
"estructura de la muerte" llena de "if anidados" o "mega
comprobaciones booleanas" en una misma sentencia. Creo que esto es
horroroso y anti-clean code. Es posible que en libro de Clean venga
algo, no lo he terminado. En Java había pensado que igual, una forma
efectiva sería usando introspección pero por otro lado eso es
complicarse la vida bastante.

¿Cómo lo hacéis vosotros? Entiendo que esa responsabilidad debería ser
del objeto que contiene la información, es decir, que contiene los
campos que necesito saber si están llenos, nulos o vacíos. Eso estaría
genial pero, como es el caso, no puedo tocarlo, es heredado.

Busco algo diferente de:

if (objeto.getValue == null) {
} else if (objeto.getValue2 == null) {
} else if....

Cualquier cosa es bienvenida! :) Gracias!

Javier Acero

unread,
Oct 27, 2010, 12:10:30 PM10/27/10
to artesanos-...@googlegroups.com
Hola Kini.

Yo llevo dándole vueltas al tema de la validación desde hace tiempo, pero mi problema va por otro camino (por el uso de Hibernate Validator...). Así que soy todo ojos para lo que se diga en este hilo.

No sé si será exactametne lo que estás buscando, pero echa un ojo al patrón especification que define Eric Evans en DDD.

Salu2.
--
Javier Acero
@jacegu

Jesus Jimenez

unread,
Oct 27, 2010, 1:20:32 PM10/27/10
to artesanos-...@googlegroups.com

No se si es exactamente lo que necesitas y no se que opinión tendrán los demás, pero te cuento lo que hice hace poco en un proyecto (igual es un poco feo pero me hizo ahorrar mucho tiempo).

Me creé una clase que recibiendo cualquier tipo de objeto, obtenía todas los atributos y los que tuvieran una anotación @Obligatorio (hecha por mi) me comprobaba que no estuviera a null, vacío, mayor que 0 o lo que le correspondiera según el tipo. Al final no conseguí dejarlo todo lo fino que me hubiese gustado pero no quedó tan mal. Quizás con polimorfismo hubiese quedado mejor.

Saludos.

El 27/10/2010 18:10, "Javier Acero" <j4c...@gmail.com> escribió:

Hola Kini.

Yo llevo dándole vueltas al tema de la validación desde hace tiempo, pero mi problema va por otro camino (por el uso de Hibernate Validator...). Así que soy todo ojos para lo que se diga en este hilo.

No sé si será exactametne lo que estás buscando, pero echa un ojo al patrón especification que define Eric Evans en DDD.

Salu2.

El 27 de octubre de 2010 18:00, Kinisoftware <kiniso...@gmail.com> escribió:


>
> Buenas a tod@s,
>
> hoy me he vuelto a encontrar con un caso, recurrente creo yo, en

> muchas a...

Javier Acero

unread,
Oct 27, 2010, 1:25:50 PM10/27/10
to artesanos-...@googlegroups.com
Jesús, eso mismo lo tienes con Hibernate Validator, sin necesidad de implementar nada. Y al contrario de lo que pueda parecer no hace falta usar Hibernate para usarlo (aunque si lo usas con Hibernate valida las anotaciones al hacer una insercion o actualización).

Salu2.

Jesus Jimenez

unread,
Oct 27, 2010, 1:32:47 PM10/27/10
to artesanos-...@googlegroups.com

Sí, lo que hice fue copiar lo que hace Hibernate, ya que no sabía que se podía usar el Validator sin usar Hibernate... para la próxima ya lo se :)

El 27/10/2010 19:25, "Javier Acero" <j4c...@gmail.com> escribió:

Jesús, eso mismo lo tienes con Hibernate Validator, sin necesidad de implementar nada. Y al contrario de lo que pueda parecer no hace falta usar Hibernate para usarlo (aunque si lo usas con Hibernate valida las anotaciones al hacer una insercion o actualización).

Salu2.

El 27 de octubre de 2010 19:20, Jesus Jimenez <yey...@gmail.com> escribió:


>
> No se si es exactamente lo que necesitas y no se que opinión tendrán los demás, pero te cuento ...

Eduardo Ferrández

unread,
Oct 27, 2010, 1:39:04 PM10/27/10
to artesanos-...@googlegroups.com
Las anotaciones son invasivas y, si no puedes modificar la clase sobre la que quieres aplicar las validaciones Hibernate Validator también te permite declararlas usando ficheros XML


(ejemplo copipasteado)

Agustín Ramos

unread,
Oct 27, 2010, 1:47:15 PM10/27/10
to artesanos-...@googlegroups.com
Hola

Te presento 3 opciones:

* En Java: Usar alguna implementación de JSR 303 (e.g. Hibernate Validator).
No es necesario que modifiques los objetos que tienes que validar, ya que puedes
especificar las validaciones mediante XML (aunque ciertamente tienes que escribir mucho más).
Con JSR 303 tienes la ventaja de que las validaciones las aplicas en el momento que
quieras y en la capa que quieras. Otra característica muy útil es que puedes definir
grupos de validaciones, de tal manera que no siempre tienes que aplicar todas las validaciones
definidas para un objeto, ya que las organizas desde diferentes perspectivas de validación.

* Hacerle caso a Javier y modelar objetos Specification como lo describe el libro DDD.
(hay una versión corta y gratuita en el sitio de InfoQ: Domain Driven Design Quickly)
Esto tiene la ventaja de que no introduces ningún framework nuevo, y además es más fácil
de leer la intención de las validaciones. Otra característica es que las validaciones
pueden ser elementos que se componen en validaciones más elaboradas.

Espero sea de ayuda.

Agustín Ramos

Agustín Ramos

unread,
Oct 27, 2010, 1:48:01 PM10/27/10
to artesanos-...@googlegroups.com
Eran solo 2... lo siento! :)

Agustín Ramos
Software Craftsman

José Manuel Beas

unread,
Oct 27, 2010, 4:28:15 PM10/27/10
to artesanos-...@googlegroups.com
¿Por qué validar si es null? ¿Por qué construyes los objetos y
permites preguntar por atributos que están a null? ¿Por qué no usar el
patrón NullObject para esos? O mejor aún, ¿hacer que el objeto
responda cosas que tengan sentido? ¿Tiene sentido responder null a
algo como "dime qué edad tienes"? Quizás deberías releer tu artículo
sobre el modelo anémico vs modelo rico ;-)

Un saludo,
JMB

Joaquín Engelmo Moriche

unread,
Oct 28, 2010, 3:13:01 AM10/28/10
to artesanos-...@googlegroups.com
Buenas,

gracias a todos por vuestras respuestas! Estuve leyendo el tema de "Specification" y, aunque me parece buena idea, creo que no es exactamente lo que necesito. Sería lo adecuado para la validación de entre objetos como el ejemplo de "Cliente - se le puede aplicar descuento - Producto" pero con el tema de validar si un campo de una clase es nulo o vacío me parece demasiado (me parece).
Me gusta más el tema de Hibernate aunque veré si hay alguna alternativa más de la JSR, en cualquier caso veremos lo que me da tiempo a implementar porque decir: "está opción es mejor, permite añadir validaciones más fácilmente, etc, no suele ser válido para -gastar- tiempo en ello" ¬¬

Al señor Beas :) yo no construyo esos objetos, que más quisiera, sino hubiera usado algo así como una lazy-initialization o lo que sea y nunca retornará nulos. Esta claro que, por eso mismo, no tiene sentido que haya cosas que puedan contestar eso :)

Un saludo
--
"Compartiendo el agilismo"
Agile Open Space 2010 - Barcelona 12 y 13 de noviembre

José Manuel Beas

unread,
Oct 28, 2010, 3:14:21 PM10/28/10
to artesanos-...@googlegroups.com
Señor Engelmo :)

¿De dónde vienen esos datos pues? ¿De un ORM? 
Si tienes un DAO, el DAO sería el sitio para "rehidratar" los objetos de negocio (con una factoría a la que alimentas con los datos que recuperas de la BD, p.ej.). Salvo que tengas un modelo anémico... ;-) en cuyo caso, sigue sufriendo mientras arrastras tu modelo de datos entre capas... :-D

Un saludo,
JMB

Leo Antoli

unread,
Oct 29, 2010, 6:47:42 AM10/29/10
to artesanos-...@googlegroups.com
Hola JM,
esto es un poco offtopic del tema original, pero tiene que ver con lo de null.

en lo que preguntabas de que si tiene sentido responder a que edad tienes , a lo mejor si tiene sentido reponder null si no lo sabes mejor que devolver 0 ;-)

depende del caso creo si que puede haber usos legitimos de null, sobre todo con objetos mutables (para String no hay problema en devolver siempre el mismo "") que tendrias que devolver cada vez una copia (o una version inmutable al estilo de Collections.unmodifiableCollection). Y si devuelves un objeto compuesto como array, coleccion, etc., a ver si habra que hacer copias deep para asegurarte...

p.e. para devolver un telefono con un objeto tuyo Phone, puedes o devolver null, o devolver un Phone con un metodo isValid (supongo JM que te refieres a algo asi).  

En Effective Java de Joshua Bloch recomiendan no devolver null para los arrays y colecciones sino devolverlos vacios (totalmente comprensible), pero no se si se puede extrapolar a cualquier tipo de objeto como idea general ;-)

(perdon por no poder tildes pero tengo un teclado nuevo y aun no me he hecho con el)

Saludos,
Leo



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

Leo Antoli

unread,
Oct 28, 2010, 10:00:57 AM10/28/10
to artesanos-...@googlegroups.com
Hola Kini,
pues yo como tú mencionabas efectivamente uso introspección para estas cosas. Me he hecho unas cuantas funciones de conveniencia para ello.

te podrías hacer por ejemplo una funcion que le pasas cualquier objeto y comprueba que todos los métodos get sin parametros devuelven no null  (o p.e. que le pases también de argumento la lista de parámetros que sí pueden devolver null, etc.).    

Igual que para comprobar muchos datos. P.e. si quieres probar arrays (para listas es similar), me suelo meter en un array el nombre de propiedades que quiero probar y el valor esperado...

String[] propertyVector = { "campo1", "campo2", ... };

String[][] listaEsperada = {
{ "valor1", "valor2", ... },
{ "valor1b","valor2b", ... } , ... }


for (int i = 0; i < lista.size(); i++) {
    Elm elm = lista.get(i);
     checkProperties(i, elm, propertyVector, listaEsperada[i]);
}

Por instrospección se va llamando p.e. al getCampo1, ... , etc. y se comprueban los valores.


Saludos,
Leo


Saludos,
Leo



2010/10/28 Joaquín Engelmo Moriche <kiniso...@gmail.com>
nstr

German DZ

unread,
Oct 29, 2010, 12:11:48 PM10/29/10
to artesanos-...@googlegroups.com
Por regla general, los nulos son feos, le obligan a chequear al que envía el mensaje para asegurarse que recibió una respuesta "usable".

Si el mensaje es edad al objeto empleado, espero una edad nunca un nulo. Si mi lógica de negocio admite no saber la edad, prefiero una excepción, si no admite no saber la edad nunca espero null y listo... un null sería un error en runtime no esperado del cual no tengo recuperación posible.

Si no entiendo mal el problema original venía de como comprobar el estado de un objeto "formado" a partir de una interfaz con algo externo no confiable (usuario, servicio de 3ros, etc). En este caso el problema está en la vista y ahí puedes tener un un builder que trate (transforme, valide, etc) la información capturada (poco confiable) y si todo está bien, te devuelva un objeto cuyo estado sea válido (si por diseño se permiten estado inválidos de objetos, vamos mal).

GDZ

2010/10/29 Leo Antoli <leo.a...@gmail.com>

José Manuel Beas

unread,
Oct 29, 2010, 4:35:20 PM10/29/10
to artesanos-...@googlegroups.com
Leo, mi respuesta es literalmente la misma que la de GDZ. :-)

Para más hincapié: a tu sugerencia de "isValid" te respondo con "si por diseño se permiten estado inválidos de objetos, vamos mal" ;-)

Leo Antoli

unread,
Oct 29, 2010, 5:51:46 PM10/29/10
to artesanos-...@googlegroups.com
Hola,
para entender un poco más vuestra postura, si una Persona tiene un Telefono que puede ser opcional, ¿ como lo hariais ?

me parece que un try/catch es mas engorroso que comprobar un null. por cierto, ¿ os referis a excepciones check o  unchecked? (supongo que checked para dejar claro que el telefono puede no existir).  y comprobar un null es practicamente igual que llamar a un isValid o isEmpty o como quieras llamarlo cuando no la Persona no tiene Telefono.   Yo creo que lanzar excepciones debería ser solo para condiciones excepcionales (valga la redundancia), pero no p.e. cuando se pregunta por un campo que es opcional.

con lo de isValid no me referia a un objeto invalido, sino vacio o que no tenemos informacion de él. P.e.  una aplicación de atención al cliente que coge datos de una Persona, y el Telefono es un dato opcional, si quiere el cliente lo da y si no no.  No se muy bien a que os referis con permitir estados invalidos de objetos, el estado de Persona es igual de valido si devuelve para Telefono un null, un NullObject o lo que se quiera mientras esté bien documentado el comportamiento. 

pues lo dicho, ¿ para este ejemplo como lo hariais ?   no veo el inconveniente de usar null en este caso.

Saludos,
Leo


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

José Manuel Beas

unread,
Oct 30, 2010, 4:34:30 AM10/30/10
to artesanos-...@googlegroups.com
Un teléfono opcional no es una excepción. Puedes devolver un
TeléfonoNoProporcionado (patrón NullObject)

--
Un saludo,
Jose Manuel Beas

http://agilismo.es
http://jmbeas.iexpertos.com
http://twitter.com/jmbeas

José Manuel Beas

unread,
Oct 30, 2010, 4:36:40 AM10/30/10
to artesanos-...@googlegroups.com

German DZ

unread,
Oct 30, 2010, 5:46:46 AM10/30/10
to artesanos-...@googlegroups.com
Nos metemos en algo más interno que tiene que ver con la definición del dominio del problema. Si el teléfono es solo un "campo" en un formulario... entonces creo que debe ser solo un atributo, incluso si es parte de un formulario tiendo a creer si existe un objeto Teléfono o MedioDeContacto o algo así. Si ese formulario se supone fue "completado", entonces asumo que la sección "Como contactar" está completa, pero si no disponemos del número del teléfono, justamente esa es la información un String.Empty. No tener un objeto MedioDeContacto (osea null) me deja en la duda si es que no le pidieron la información o si es vacía.

En otro tipo de dominio, es más razonable que aún no exista ese Teléfono, pero entonces se supone que hay más lógica asociada a la posibilidad de no existencia.

Mi último pensamiento es que si esta lógica se encuentra toda en la "Vista" o capa presentación o algo así.. pierde un poco de sentido la discusión filosófica, porque esa vista será un trozo de código muy específico de la solución y tiene menos que ver con el modelado del problema en si.


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

José Manuel Beas

unread,
Oct 30, 2010, 8:47:39 AM10/30/10
to artesanos-...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages