viernes, 1 de junio de 2007

Extreme Validation

El viernes 18 de Mayo de 2007, Andres Valloud y Leandro Caniglia dieron una charla en la materia de Programación Orientada a Objetos sobre un concepto que llaman "Extreme Validation".
La idea es interesante y la presentación salió muy bien. El modelo que presentaron se puede ver en el paper que Leandro presento en Smalltalk Solutions 2007
El otro dia se me vino a la cabeza un modelo de validadores distintos al que ellos usan y queria comentarlo para ver que les parece.
La idea es cambiar un poco el punto de vista y tener una clase de validador por tipo de validación. O sea, la jerarquía de clases quedaría algo así:

Validator
...IsRequiredValidator
...IsNumberValidator
...IsStringValidator
... (bla bla)
...CompositeValidator

Validator definiria el mensaje #validate: anObject que seria abstracto. Cada validador implementaria lo necesario según el tipo de validación que hace. El CompositeValidator delegaría el #validate: a cada validador que lo compone.
Luego, cada clase conocería su validador (quizá a travez de una variable de instancia de clase) que en la mayoría de los casos seguramente sería un CompositeValidator. Por ejemplo:

Person class>>initializeValidator

validator := CompositeValidator
with: (IsRequiredValidator aspect: #name)
with: (IsNumberValidator aspect: #age between: 0 and: 100) ... bla bla bla.

Lo que vi de interesante de hacer estos cambios es:
1) No se tiene una jerarquía paralela de validadores puesto que hay validadores por tipo de validación, no por objeto a validar
2) Se puede controlar la secuencia de validación puesto que el CompositeValidator seguiría la secuencia de validación a patir de como se lo creo.
3) No seria necesario crear los validadores constantemente (como creo que lo están haciendo, a menos que los cacheen en algún lado), solo se crearían una vez con un mensaje como #initializeValidator...
4) Cuando se crean nuevas clases del modelo, no es necesario crear nuevas clase de validación, simplemente se componen validadores existentes. Esto es indicio de un buen modelo, o sea, aparecen nuevos elementos en el dominio de validación que implican solo la creación de nuevos objetos en mi modelo y no la creación de nuevas clases puesto que lo aparecen son validadores y no nuevos "conceptos de validación".
5) La clase validator no será una "library" de funciones de validación, sino que habra una clase de validación por cada tipo de validación. De esta manera se está reificando el concepto de tipo de validación y no se está implementado en Validator responsabilidad relacionada a validaciones que necesitan otros objetos.

Quizá la desventaja es que el CompositeValidator debería implementar algo similar a lo que hace TestCase y TestCaseResult para guardarse el resultado de validación, motivo por el cual Andrés había sublasificado Validator de TestCaseAbstract en primera instancia, pero no lo veo problemático.
Según lo que enseñamos en POO, sublasificar Validator de TestCaseAbstract no es correcto conceptualmente. El motivo se debe a que TestCaseAbstract tiene más comportamiento (responde más mensajes) del que un Validator realmente representa . En este caso en vez de que Validator tenga menos comportamiento que el necesario (un error común de análisis del dominio), tiene más (un error común cuando se "abusa" el uso de la subclasificación). Esto lo convierte en un Validator+un TestCase, y por lo tanto sabrá responder mensajes que no le corresponden, produciendo inconsistencias y errores.

Para aquellos que estuvieron en la presentación, ¿qué les parece?

3 comentarios:

Andres dijo...

Hernan,

A pesar de que en los ejemplos de validacion no he visto la necesidad de usar cosas como assert: o should:, heredados de TestCase, no me parecio necesario cerrar explicitamente esa puerta. Pero... quiza sea una posibilidad que no haga falta despues de todo.

Gracias por la critica :),
Andres.

AF dijo...

Comparto lo que decís de no duplicar jerarquías, o sea que desde ese punto de vista me agrada... lo que mucho no me agrada es la posible extensión del método de inicialización, ya que tomando dos o tres líneas por aspecto (ej que sea vacío o que sea una dirección de mail válida), en un objeto con 5 v.i. te queda un método de unas 15 líneas... De todas formas me parece súper interesante, tal vez con un poco de syntax-sugar se pueda mejorar (algo así como componer validadores con mensajes tipo & y |)?

Hernan Wilkinson dijo...

Que tal AF,
lo que sucede es que si tenés tantas opciones quiere decir que el objeto hace muchas cosas y seguramente conviene sacarle responsabilidades y partirlo en varios objetos...
Otra opción es utilizar un builder para crearlo, de esa manera no hay que tener mensajes tan largos y solamente vas configurando el builder hasta que le pedís el validator con todas las opciones configuradas correctamente