martes, abril 22, 2008

Inversión de control

En las dependencias
Para utilizar dependencias alcanza con subclasificar Object o Model. La clave esta en los métodos #chanded: que heredamos de ellas, los cuales esconden todo lo que pasa tras bambalinas para hacer funcionar las notificaciones.

El “framework” llama al código del usuario (#update:). Llamamos a esto inversión de control

En el “framework” de construcción de interfaces
Uno de los pasos claves en la construcción de GUIs en Visualworks es la subclasificación de ApplicationModel.

Nuestro ApplicationModel va a recibir muchos mensajes que nosotros nunca enviaremos desde nuestro código. Muchos de ellos los mencionamos al configurar los widgets (actions y aspects). El método #windowsSpec casi podemos olvidar que existe porque nunca enviamos explícitamente el mensaje y casi nunca miramos su implementación.

El aplicación model puede redefinir los métodos #preBuildWith:;
#postBuildWith:; #postOpenWith: . La aplicación (el código del escrito por nosotros) nunca envía esos mensajes. Existen como gancho (hooks) para que, mientras el “framework” de interfaces tiene el control, yo pueda hacer cosas como esconder/desactivar widgets, dar últimos toques de configuración a la GUI (como elementos seleccionados en una lista), etc.
Vean el método #openInterface:withPolicy:inSession: en ApplicationModel. Se trata de un template method en el que el objeto se envía a si mismo los mensajes antes mencionados.
La clase ApplicationModel provee implementaciones “vacias” de los métodos #preBuildWith:; #postBuildWith:; #postOpenWith:. De esta manera, las subclases pueden optar por implementarlos o no.

En SUnit
Para definir un test subclasificamos TestCase.

Hay tres elementos clave en un test. Su método #setup (donde se prepara el fixture de objetos que voy a necesitar para el test), su método #tearDown (donde se liberan recursos que pude haber generado para el test y no se van automáticamente) y los metodos #test*.

Uno nunca envía explícitamente los mensajes #setup, #tearDown o alguno de los #test* a un TestCase. Uno crea un test indicando cual de los tests quiere correr (myTestCase := MyTestClass selector: #testSomething) y luego le dice que corra (myTestCase run).

Luego de enviar el mensaje #run a un TestCase, el mismo termina recibiendo el mensaje #runCase para el cual existe un template method implementado en TestCase que dice algo como:

>>runCase
[self setUp.
self performTest] sunitEnsure: [self tearDown]


Por eso uno implementa #setup y #tearDown aunque nunca los envíe. Es un caso mas de inversión de control

Inversión de control y el template method
En los tres casos que vimos anteriormente la inversión de control se consigue/introduce gracias a un template method (y a la herencia). Ese es un mecanismo muy comúnmente utilizado para construir clases (o conjuntos de clases) reusables.

2 comentarios:

Laucha dijo...

Casco en la clase sobre frameworks hablaste sobre los frameworks como unos Dioses todo poderosos que nos regalaban diseños de software de proposito especifico para que nosostros(el usuario) reuse dicho diseño y mucho mucho código.
El tema es que como a todo Dios hay q regalarle algún sacrificio para que Él nos ayude, no me refiero a sacrificios tales como ir a la iglesia todos los domingos, sino a las desventajas de los Frameworks, una desventaja desde mi humilde punto de vista es que nos acota la flexibilidad y que debemos aprender a usarlos correctamente.
Pero como vos tenes membresia en esta religión de los frameworks te lo pregunto.
¿Que desventajas contraen el usar frameworks, hay algún tipo de Framework que nos provea solo el diseño con poco o nada de código?

Alejandro Fernandez dijo...

Hola Laucha,
¿tan fanático de los frameworks sueno? :)
El precio de un framework se paga mayormente por adelantado durante su desarrollo. Lleva mucho esfuerzo. Claramente, al adoptar un framework que no esta bien maduro poder pagar algún costo más como por ejemplo, falta de buena documentación, bugs que no podes corregir porque no querés meterte en el framework (al fin y al cabo, usas un framework para ahorrarte el esfuerzo de hacer todo vos mismo), etc. Lo de acotar la flexibilidad es subjetivo: uno elije un framework porque quiere ahorrarse tiempo y esfuerzo; eso implica hacer las cosas como pensó dijo quien desarrollo el framework. Es un trade-off. Siempre podés buscar otro que te guste más o desarrollar todo desde cero (no lo recomendaría).
Respecto a la segunda pregunta, un framework es por definición "implementación/código".