martes, 14 de abril de 2009

Magritte 2

Algo que siempre digo y me olvidé de comentar en el post anterior es que "es muy fácil criticar pero difícil hacer". Mis comentarios del post anterior fueron todas crítticas, sin embargo Magritte también tiene cosas muy interesantes como el manejo de mementos para la edición de objetos, la posibilidad de configurar el framework (todo puede ser cambiado, como el container, las descripciones, los componentes), etc. 
Una aclaración que me parece necesaria para no parecer siempre negativo.

Magritte

No voy a escribir sobre arte, no, este post no es sobre René Magritte sino sobre el framework creado por Lukas Renggli para ayudar en el desarrollo de aplicaciones utilizando metraprogramación.
Ayer estuve leyendo bastante sobre el mismo y jugando un poco con él. Es un framework que permite rápidamente obtener una representación visual de objetos del modelo, creando en ellos una serie de descripciones. Por ejemplo, si tenemos la clase Address, creando métodos que se llaman "descriptionXxx" donde Xxx generalmente tienen que ver con los nombres de las variables de instancia, se puede obtener un componente SeaSide o Morph para instancias de Address.
Veamos un ejemplo del tutorial que ofrecen:

descriptionStreet
^ MAStringDescription new
autoAccessor: 'street';
label: 'Street';
priority: 10;
yourself

Esta sería la descripción para la variable de instancia 'street' de Address (o MAAdressModel como se llama en el tutorial... un nombre poco feliz desde mi punto de vista puesto que la palabra Model está de más). Veamos que significa cada cosa:
1) autoAccessor: Significa que se accederá a 'street' con los mensajes #street y #street:, si no existen los creará, pero no solo eso, creará también la var. de instancia si no existe.
2) label: String que se utilizará para identificar el entry field de Street
3) priority: Posición en la que debe aparecer el campo en el componente visual. Menos prioridad significa más arriba, más prioridad significa más abajo.

Veamos ahora otra "descripción":
descriptionPlz
^ MANumberDescription new
autoAccessor: 'plz';
label: 'PLZ';
priority: 20;
min: 1000;
max: 9999;
yourself

Este describe el código postal. Más observaciones:
4) Nótese que priority es 20, lo que significa que irá luego de street... no se si notaron que hay 10 números entre el priority de street y este, ¿por qué?, para poder poner componentes visuales entre street y código postal sin necesidad de modificar estos métodos.
5) min: y max: indican los valores numéricos máximos del código postal

Por último, quería mostrar esta "descripción" también:
descriptionCanton
^ MASingleOptionDescription new
options: #( 'Zurich' 'Bern' 'Luzern' 'Uri' 'Schwyz' 'Unterwalden' 'Glarus' 'Zug' 'Freiburg' 'Solothurn' 'Basel' 'Schaffhausen' 'Appenzell' 'St. Gallen' 'Graubunden' 'Aargau' 'Thurgau' 'Ticino' 'Vaud' 'Valais' 'Neuchatel' 'Geneve' 'Jura' );
reference: MAStringDescription new;
autoAccessor: 'canton';
label: 'Canton';
priority: 40;
beSorted;
yourself

Es la utilizada para elegir un canton (provincia). Observaciones:
6) Los distintos cantones están hardcodeados en la descripción

Bien, ahora voy a dar algunas opiniones sobre los puntos que estuvimos viendo:
1) Nunca usaría autoAccessor. No sirve cuando se está desarrollando un app en serio puesto que crearía una variable aún cuando el nombre de la misma está mal escrito, es muy peligroso dejar la creación de variables y métodos a herramientas en vez de hacerlo uno. Por otro lado, si se hace un rename de la variable este "descriptor" no se enteraría... ese es uno de los problemas de este tipo de frameworks, la falta de integración con las herramientas de desarrollo comúnes y también por no estar reificadas las variables en Smalltalk. Para solucionarlo utiliaría #selectorAccessor: o escribiría un test que se asegurará la consistencia de este descriptor.
2) Sobre label. Acá es donde me empieza a gustar menos la cosa. En una clase del modelo (Address) estoy poniendo información sobre que quiero que aparezca en la view, un acoplamiento poco deseado. Además este label podría cambiar de view en view. La solución que proponen es obtener una copia del descriptor y modificar el label para ese caso... hmm, más acoplamiento.
3) y 4) priority: Más acoplamiento. Entre el modelo y la view por estar este número en un método del modelo y entre los descriptores mismos por utilizar entre ellos un número mayor que el otro para indicar que va después. Para el primer caso, ¿qué le importa al modelo en que posición se va a mostrar el componente visual para alguna de sus variables de instancias?. Para el segundo caso, ¿no sería mejor tener un objeto que indique la secuencia en la que debe ir cada componente visual? una OrderedCollection de descriptores por ejemplo?. De esa manera el hecho de la posición no estaría acoplado al descriptor sino que sería responsabilidad de otro objeto. Por otro lado, ¿por qué dejar 10 número entre uno y otro? ¿no se pueden usar número reales? Si se puediesen poner números no enteros (cosa que no probé aún) no habría necesidad de dejar 10 números entre una descripción y otra puesto que todos sabemos que siempre hay números entre dos números reales. 
5) Que las validaciones de los objetos no estén con los mismos no me parece una buena solución. Si el código postal de Suiza tiene que estar entre 1000 y 9999, debería existir una abstracción para dicho ente que además debería encargarse de realizar esta validación. Separar la validación del objeto en si mismo no representa correctamente el ente que se está modelando, lo cual trae problemas a posteriori, como por ejemplo cargar direcciones desde un archivo. En ese caso, ¿quién valida que el código postal sea un número entre 1000 y 9999?, ¿o para hacerlo también tengo que usar Magritte?. Digamos que uso Magritte, ¿qué pasa entonces cuando creo una dirección desde el workspace? no voy a usar Magritte para eso... 
6) Por más que es un ejemplo y los cantones están hardcodeados por ello (imagino), supongamos que no, ¿cómo los obtendría?. Tendría que colaborar con el objeto encargado de mantener la lista de cantones válidos. Algunos propondría utilizar una clase, "Cantones" por ejemplo que tenga una class variable con las cantones válidos, una porquería desde mi punto de vista. Si vamos a hacer eso utilicemos una variable global, "Cantones" y listo, ¿para qué crear una clase?. Pero sea una u otra la solución, el acoplamiento que se crea es enorme! ahora esa descripción no va a funcionar con otra cosa que no sea esa lista de cantones! que además está referenciado desde un método de la clase Address! o sea que no puedo usar Address en otro contexto!... una muy mala solución y que surge de la necesidad de indicarle los cantones en la "descripción" en vez de indicarselos a la view directamente al momento de construirla.

En fin, mi conclusión por ahora es que Magritte, como todo este tipo de frameworks, sirve para hacer una app rápido y chiquita si no te importa mucho el diseño y cómo la vas a mantener. Ahora, si querés hacer una app en serio o no utilices Magritte o hay que tomar algunas decisiones como:
1) Que las descripciones no estén en el modelo
2) Que el orden de los componentes estén en otro objeto y sea configurable por view
3) Que la validaciones no estén en las descripciones
4) Que no exista acoplamiento entre la descripción y los elememtos que muestran las views

Una última cosa que acabo de acordarme, me parece una decisión muy poco feliz la que tomaron de que todos los objetos sepan responder #description para devolver una colección de descriptores de Magritte. ¿por qué no lo llamaron #magritteDescription o algo así y de esa manera no impedían utilizar ese mensaje en el modelo para cosas que tengan que ver con el modelo?.... en fin.
Voy a mandar un mail a la lista de Magritte con estos comentario para ver que soluciones/respuesta obtengo. Los mantendré informados.


Mapeo Objeto-Relacional

El mapeo de objetos a base de datos relacionales es un tema bastante complicado y estudiado en nuestra profesión, aunque siempre aparecen nuevos frameworks que supuestamente solucionan los problemas que se generan en este mapeo, pero que finalmente crean nuevos... en fin, vamos a tener que esperar mucho hasta que la gente se de cuenta que el problema es de fondo y no de forma... mientras tanto les paso un link que me recomendaron sobre este tema:

viernes, 3 de abril de 2009

Nueva Etapa Laboral

Aquellos que tengan Facebook habrán visto que a principio de semana puse que estoy empezando una nueva etapa laboral... no comenté muchos detalles allí, así que quería utilizar este medio para aclarar un poco más de que se trata.
Con unos amigos estamos armando una empresa en la que ofrecemos servicios de desarrollo de aplicaciones complejas, capacitación y coaching de objetos, patrones, frameworks, tdd, metodologías ágiles y diagnósticos sobre código y diseños de aplicaciones existentes. 
No creo que sea necesario explicar a que me refiero con aplicaciones complejas o capacitación. Si quizá un poco sobre a que me refiero con coaching. Cuando capacitamos, no nos interesa únicamente dar los cursos, sino hacer un seguimiento  con la gente una vez terminados. Lo que ofrecemos es realizar pair programming con los asistentes para que realmente apliquen lo que enseñamos. Esta es la única manera de agregar valor en la capacitación y que realmente la gente aprenda.
Seguramente también sea necesario explicar a que me refiero con "diagnóstico de código y diseño". Bueno, ustedes saben que hay muchas empresas que ofrecen consultoría para ayudar a mejorar los procesos de desarrollo, implementar un sistema de SCM, etc, pero pocas (sino ninguna) se mete a bailar con la más fea, donde realmente hay que moverse y demostrar experiencia y conocimiento; pocas se meten en el código y el diseño de un sistema existente y ofrecen un diagnóstico sobre cómo está hecho y cómo se lo puede mejorar. A esto es lo que apuntamos con este servicio, la idea es arremangarnos, ver el diseño y el código del sistema que les parezca importante y darles un diagnóstico del mismo. Este diagnóstico sería similar a lo que nos da un médico clínico cuando lo visitamos. Nos dice en qué andamos mal y qué deberíamos hacer para mejorar, etc; nosotros haremos lo mismo. Ver un sistema, analizar su diseño, cómo está codificado para luego generar un informe que indique su "grado de salud" (qué tan enfermo está, cuanto va a vivir, qué se puede hacer para alargar su vida, etc). Sinceramente no conozco empresa que ofrezca este servicio puesto que es muy difícil de realizar y hay que estar muy capacitado para obtener buenos resultados. Nosotros tenemos la capacidad y conocimiento para hacerlo y es un valor agregado muy importante que ofrecemos.
Bueno, basta de marketing por un rato.... Respecto del blog, voy a intentar postear más seguido ahora, aunque en realidad este cambio aún me está requiriendo más tiempo del que esperaba, imagino que cambirá en unas semanas. 
Por otro lado no quiero dejar pasar la oportunidad de agradecer y mencionar lo feliz que fue y es para mi trabjar en Mercap, he aprendido muchísimo a nivel técnico y humano, hemos tenido grupos de personas muy lindos y hemos logrado cosas que no he visto en ninguna otra empresa. De hecho, voy a seguir trabajando algunas horas en Mercap puesto que es una empresa que realmente amo, por la gente, por lo que hacemos y por lo que hicimos. Por eso quería agradecer también por este medio a Alejandro (dueño de Mercap) por la oportunidad que me da de seguir formando parte de la empresa y apoyarme en este nuevo emprendimiento.
En fin, ya cerrando y volviendo al marketing :-), si alguien está interesado es saber un poco más qué ofrecemos, tiene interés en conocer precios o contratar algún servicio, no deje de avisarme!