domingo, 31 de agosto de 2008

5 blogs recomendados 5

Hoy es el Día del blog (para el que por lo menos no hay que comprar regalos), y todo el mundo está haciendo sus recomendaciones.

Antes una aclaración: no me gustan las comparaciones del tipo "este es mejor que tal otro". Me molesta tener que poner a uno por encima del otro, así que están ordenados de menor a mayor cantidad de suscripciones según mi reader.

Bueno, aquí van:

  • Un Punto Azul Pálido, de Improbable. Difícil de clasificar. Sistemas, desarrollo de software, diseño de aplicaciones, equipos, programación (pero sin bajar al detalle de "ahora copiamos este código en tal lugar"), buenas prácticas, malas prácticas, anécdotas, algo de filosofía y muchas referencias a temas que nunca hubiésemos relacionado con el tema del post. Es un blog que empezó en Junio de este año, por lo que tiene pocos pero muy buenos artículos.
  • Culto Al Bizarrismo es... bueno, nadie mejor que ellos mismos para describirse: "Todo eso que te produce rechazo pero que no podés dejar de ver...". Una colección de cosas simplemente bizarras que aparecen por ahí. De esta caja de pandora puede salir cualquier cosa, como por ejemplo: redoblantes. Como verán no soy un tipo serio ni demasiado inteligente, con esto me sobra para matarme de la risa...
  • Pequeñas historias de mi trabajo está inactivo desde Junio... ¡espero que vuelva! El autor es, en sus propias palabras "Director de Proyecto en una multinacional de consultoría de tecnología, informática y todo lo demás..." Post cortitos que van armando la trama de su vida laboral, interesante y divertido.
  • Dirección de Proyectos. El título lo dice todo. Para conocer del tema sin tener que ser un experto en ello.
  • De consultor a Director de TI. Si bien "no es un blog, es una historia" es imperdible. Yuki relata su vida profesional cronológicamente, en forma prolija y divertida. Cada historia abarca varios post larguísimos, que lo dejan a uno más pegado que con Dexter.

sábado, 30 de agosto de 2008

Trabajo y procrastinación.

"Work is the greatest thing in the world, so we should always save some of it for tomorrow." - Don Herold

Mucha planificación, pero...

Ultimately, good planning degenerates into work.

Esta frase me la comentó un amigo en tiempos en los que vivía en USA. Según recuerdo algún profesor solía cerrar las reuniones con ella. Traducida creo que queda algo así como:

En definitiva, la buena planificación se degenera en trabajo.

Reacciones ante los errores en un sistema informático.

La reacción de cada participante en el proceso de desarrollo de un sistema ante errores puede ser muy variada... desde coleccionarlos hasta... bueno, hasta ésto (click para agrandar la imagen):

Visto en EmezetaBlog.

Clasificando mi spam (II)

Con esto de clasificar el spam, me encontré con alguno que intenta hacerse pasar por msnbc news con unos encabezados de lo más delirantes:

  • Gay Bishop Was A Wrestling Pro
  • Senator John Mccain Wishes To Have Sex With Model Heidi Klum
  • Barack Obama Caught In A Time Warp
  • Attack Of The Zombie Negroes: Dick Cheney
  • All Baseball Players May Be Indicted For Steroid Abuse
  • Arnold Says im Gay Too!
  • Spongebob Denies Reports That Hes Gay
  • Heather Mills Mccartney Arrested

Actualización: un poco de google por esas frases para caer en la cuenta de que mi spammer, si bien divertido, no es original. Casi todos son titulares de sitios de sátiras. Se me cayó un ídolo.

El capitalismo como nunca te lo explicaron.

Un video explicativo del circuito de producción capitalista... 20 minutos imperdibles, sencillito y con mucho ritmo como para no quedarse dormido. Para que no sea tan off-topic, voy a acotar que (re)conocer un problema es el primer paso para resolverlo.

Vía La bitácora del capitán.

viernes, 29 de agosto de 2008

Mensajes de error.

Tener buenos mensajes de error en una aplicación es más difícil de lo que parece... Pero bueno, eso no quita que podamos hacer leña del árbol caído.

Aquí tenemos una colección de mensajes de error delirantes, vía fabio.com.ar.

Abrace a un desarrollador.

Un video para reírse un rato: Abrace a un desarrollador y luego ponerse a llorar.

Ahora en serio: no se lo pueden perder. Vía nulleando.com.ar

jueves, 28 de agosto de 2008

Requerimientos: cuando no son asteroides sino sólo polvo cósmico.

Nota: esta entrada es una contribución de Cerebrado relacionado con la entrada Asteroides, que les recomiendo leer primero.

Hay veces en las que el requerimiento es la implementación de una solución.

¿Cómo? Analicemos.

Sí, hay veces en las que lo que se requiere es que se implemente una solución. Se entiende por solución una forma determinada, específica, de resolver de un problema. ¿Cómo? ¿No es así siempre? No, no debería ser así. El requerimiento debería ser el planteo de un problema. El equipo debería encontrar la solución.

Por las dudas va un ejemplo. Un requerimiento normalmente diría:

El sistema debe detectar que el saldo de una cuenta ingresa en rojo y alertar al ejecutivo de cuentas asignado al cliente.

Pero hay veces en las que dice:

Implementar un trigger sobre la instrucción insert de la tabla cuentas_movimientos. En este trigger, cuando sld_cnt - deb_pnd + crd_pnd sea menor a 0 insertar un registro en la nueva tabla notificaciones con los siguientes valores: ....

En vez de asteroides llega sólo polvo cósmico de esa nube de requerimientos de la que se hablaba en Asteroides.

Hay un intermediario que filtra, soluciona, resuelve... pero no comparte ni la información obtenida ni el método que usó para obtenerla.

En definitiva se requiere que escribas lo que otro pensó. Hasta ahí no habría mucho de qué quejarse, incluso hay gente que no es proactiva y a la que éste tipo de tareas le cae más que bien.

Uno implementa esa solución, sin saber qué resuelve. Actúa por el "cómo", y no por el "qué".

Pero luego ocurre un problema, un cambio en el requerimiento, la funcionalidad no trabaja como debería. Y ahora sí, nos llega un asteroide hecho y derecho con forma de reporte de error... ¿por qué no aparece de vuelta ese polvo cósmico con la solución detallada?

¿Y ahora qué se hace? En los restos del polvo cósmico original no hay piezas suficientemente grandes como para extraer información de cómo debería funcionar la cosa, ni de por qué funciona mal.

Entonces es cuando uno hace dotes de adivino, prueba y falla, busca al intermediario para sacudirle los bolsillos hasta que caiga al menos alguna piedrita... si lo encuentra (suelen tener la habilidad de aparecer y desaparecer a voluntad y escasa voluntad para ajustar sus propias soluciones). Así hasta que el intermediario queda satisfecho con lo que hemos hecho.

Puede tomar mucho tiempo, mucho esfuerzo, y el resultado puede no ser el óptimo.

¿Cuales son los resultados posibles?

  • Puede que hayamos entendido qué hicimos. Sería el mejor de los casos.
  • Puede que hayamos creído entender lo que hicimos.
  • Puede que no hayamos entendido un catzo.

Para cada una de las anteriores, puede que no nos importe... o que sí. La cosa anda, pero si vuelve a ocurrir algo en la nube (y con seguridad va a ocurrir) volveremos a recorrer el mismo penoso camino.

¿La falla es del intermediario, por no saber transmitir? ¿Por no confiar (con o sin razón) en el poder analítico de su subalterno? ¿Es nuestra, por conformarnos (y acostumbrarnos) a la información reticente? ¿Por no exigir / pedir más definiciones?

La falla es un composé de muchos puntos:

  • Comunicacional. El intermediario no sabe / puede / quiere comunicar.
  • De rango: porque cree que dar la menos información es tener más control.
  • De confianza: porque no confía en su gente.
  • De experticia: porque no sabe trabajar en equipo.
  • De incumbencia: porque el intermediario resuelve a ese nivel de granularidad aunque sus funciones no lo especifiquen.
  • De usos y costumbres: porque se han resuelto demasiados problemas de esta manera como para poder plantear la posibilidad de que haya algo malo en el método.

Ahora, la pregunta es... ¿queremos un asteroide o sólo polvo cósmico?

10 frases memorables de Los Simpsons.

Puesto 10. Abuelo Simpson: Mi hijo no es comunista, podrá ser tonto, estúpido, inútil, comunista pero nunca una estrella de porno.

Puesto 8. Homero: ¡Ya sabes como soy Marge, me gusta la cerveza fría, la tele fuerte y los homosexuales locas, locas!

Las otras 8 en este post de "10 puntos".

miércoles, 27 de agosto de 2008

eXtreme Programming es un arma peligrosa.

Algunas veces la búsqueda de la agilidad nos lleva al descontrol. Hay una zona gris en donde es fácil mezclar movimientos rápidos con desprolijidad (y sólo logramos ser torpes), eficiencia aparente con trabajo pendiente (y sólo logramos ser eficaces), cumplimiento de plazos con baja calidad (y apenas logramos llegar a tiempo a la fiesta de entrega, vestidos de traje pero sin calzoncillos). Resumiendo, a veces se confunde agilidad con velocidad.

Las presiones del negocio hacen que la búsqueda de la agilidad se vuelva obsesión (y esto es bueno). Tratamos de hacer lo menos posible de la manera más simple posible.

Así, planeamos a medida que avanzamos, nos integramos con el cliente, diseñamos a medida que construimos, construimos pensando en la reutilización y el cambio, integramos continuamente y utilizamos tests codificados en todo el proceso... o al menos eso deberíamos hacer, si seguimos los postulados de XP (Programación extrema, PE o eXtreme Programming, XP), a mi entender la metodología más obsesionada por la velocidad la agilidad.

Por desgracia muchos han leído la entrada en Wikipedia y han googleado, picando de aquí y de allí, pero pocos han leído el libro que da origen a la cosa, Extreme Programming Explained, de Kent Beck. No conozco a nadie que haya participado en un equipo ágil tal cual lo define el libro, aunque sí a algunos integrantes de equipos que de "ágiles" sólo tienen la etiqueta (no está mal tener sólo la etiqueta, siempre que uno sea consciente de ello).

Para que quede claro, antes de comenzar con el sarcasmo o de tirar ejemplos concretos: la belleza de XP radica en que es un sistema, y no una colección de partes que pueden reordenarse o intercambiarse a voluntad. Sin embargo, es esta belleza lo que lo vuelve peligroso puesto en manos de algún monito. Ya me explico.

Se suele utilizar XP menos para desarrollar que para defender lo indefendible y justificar lo injustificable por la supuesta búsqueda de "agilidad", opinando de oídas sobre un punteo de conceptos centrales. La frase "...pero XP recomienda..." debería estar prohibida en equipos que no implementan XP. Ahora sí, repartamos palos.

Monito de contacto con el cliente + Tijeritas + XP = Los requerimientos son cambiantes, toda documentación más allá de lo indispensable una pesada carga para el equipo que no aporta valor al cliente y la comunicación informal la más conveniente siempre. Entonces, como estamos muy apurados y tendríamos que haber empezado ayer, no pasemos los requerimientos por escrito. Esto es ágil.

Todos los antecedentes son correctos, eso es innegable. Pero eso no vuelve verdadera la afirmación. Lo que sigue al "entonces" es una barrabasada.

Por empezar, incluso en XP uno de los documentos requeridos (y en XP no hay muchos) es, justamente, el que especifica un requerimiento: la historia del usuario. Pensemos cuánta importancia tiene este documento que en la metodología más minimalista es requerido. Y no sólo eso. XP obliga a que el documento realmente exista, por ejemplo al centrar en él el proceso de planificación. Casi todas las tareas de XP se centran alrededor de éste documento.

Los requerimientos no son parte del sistema, los requerimientos **definen** al sistema. Por si no queda claro: yo puedo crear un sistema sin diseño, sin computadoras, sin código, sin empleados, sin nada. Puedo crear un sistema tan sólo diciéndole al cliente "haga esto y lo otro y luego esto otro". Si me pongo filosófico, puedo decir que puedo crear un sistema con sólo pensarlo (al fin y al cabo es una construcción teórica), y ni siquiera necesito comunicarlo para que exista.

Pero no puedo crear un sistema sin requerimientos, el objetivo es parte de la definición de sistema, explícitamente. En un sistema informático, los requerimientos son el objetivo, y por tanto son lo que hace que el sistema funcione. ¡En serio! A ver: tengo un programa que cada vez que lo ejecuto hace que Windows tire un BSOD... ¿Funciona? No sé, a ver los requerimientos... "es un sistema contable": entonces no, no funciona; "es un virus": entonces funciona perfectamente.

Ahora un poco más en serio: la memoria nos juega malas pasadas, los charcos se secan, a las palabras se las lleva el viento. Cuando surge una duda sobre un requerimiento, enormes porciones del sistema se tambalean. Si esperamos que los requerimientos cambien velozmente, tendremos que pensar en algo para no confundir los de la semana pasada con los de la anterior. Esto me ha sucedido: llega el requerimiento "A", luego el requerimiento "B = not A", luego el "A", luego el "B"... y así ad eternum. Si los cambios están separados por un par de meses jamás nos daremos cuenta de que en realidad la solución es poner un parámetro en la configuración... puedo hacer los cambios velozmente, pero que nadie me diga que eso es ser ágil.

El desarrollo de software no es más que un teléfono descompuesto entre el cliente y un algoritmo. La metodología no es más que un desesperado intento por arreglarlo. XP lo intenta minimizando la cantidad de "nodos" en la línea: el cliente mismo está al lado de los codificadores, escribiendo los requerimientos.

Conclusión: el monito de contacto ocupa un lugar clave en donde una palabra, apenas un pequeño malentendido, puede tener consecuencias imprevisibles. Sea precavido: domestique a su monito de contacto (recuerde que la letra, con sangre... entra).

Monito analista + Cuchillo dentado + XP = Los diseños se refinan durante la codificación, ya que sólo obtenemos una comprensión acabada del problema al resolverlo. Es un proceso iterativo. Por eso vos empezá programando con lo que más o menos te acabo de contar, después te paso el diseño y vemos. Esto es ágil.

De vuelta, correctos antecedentes con una conclusión mágica que sólo guarda una relación aparente con ellos.

En XP diseño y codificación van de la mano no porque sean procesos iterativos e incrementales (que se entienda: sí que son iterativos e incrementales, sólo que no es lo central en relación a éste aspecto de XP en particular), sino porque en XP parte del diseño (tal como se lo define tradicionalmente) se amalgama con la codificación, a fin de lograr una comunicación más directa entre el desarrollador y el cliente. No hay una actividad de diseño sin parte de codificación ni viceversa, por tanto un analista, a menos que pueda codificar, no podrá diseñar en un equipo XP (siempre hablando en el sentido clásico del término "diseñar").

En XP se especifica claramente que la historia del usuario le llega directamente a un par de programadores quienes, para empezar, la estiman por su cuenta (mientras el analista nos va a buscar un café), luego la planifican con el líder del proyecto (mientras el analista va por el azúcar... siempre se olvida del azúcar) y que finalmente van codificando y "elaborando el diseño" a medida que codifican (mientras el analista descansa un rato antes de volver a la máquina expendedora)...

Pero bueno, ya que éste analista trabaja en un equipo que no adopta XP, que haga el análisis que corresponde en vez de justificarse en cualquier cosa y pasarle un garabato de compromiso a un pobre programador que encima terminará haciéndole el trabajo, ya que el caradura no tendrá mejor idea que acercarse luego y preguntar "¿cómo lo resolviste?"... eso si alguna vez elabora los famosos documentos.

Luego hay un error en el código y no hay forma de saber qué es lo que el sistema debería hacer... ah, y es culpa del programador, que no siguió con las especificaciones (que él mismo le pasó -sin querer- al analista).

Para terminar esta sección, un divague futurista... un monito analista no debería ensalzar demasiado a XP. Esta metodología nos lleva por una senda que puede llegar a determinar su anulación en proyectos pequeños, tal vez en medianos y en una de esas en grandes. Lo rebaja a la categoría de ayudante de redacción (del cliente al elaborar las historias del usuario) y diseñador y ejecutor de tests funcionales... y yo me arriesgo a decir que incluso este último papel está un poco amenazado: la mayoría de los tests se pueden automatizar (sí, incluso muchos funcionales), así que si al analista no se le ocurren tests nuevos todo el tiempo, el pobre hombre ya no sirve para nada... perdón, sí sirve, está el tema del café... bueno, logramos acomodarlo, ¡bien por él! Sólo un analista es capaz de justificar su inacción utilizando una metodología que en una de esas lo deja sin trabajo (bueno, si lo pensamos bien... esto le da la razón al analista y a la metodología).

Monito programador + anteojos de recorte de la realidad + XP = El código es la documentación. Hay que diseñar a medida que se codifica. El código es compartido. Hay que tener coraje para hacer un refactory cuando es necesario. Así que no documento ni comento, charlo un rato con el analista y luego hago lo que mejor me parece donde mejor me parezca. Migré el front-end desde Java a .Net porque leí en un blog que la nueva versión es muy superior. Luego lo volví a Java (recodificando, no hacia atrás) ya que en otro blog aprendí varios temas de performance que me hicieron cambiar de idea. Luego descubrí Silverlight así que lo implementé (me quedó muy bonito) pero finalmente me enteré de que sigue en beta... me pareció que no era estable, así que en definitiva quedó en .Net. ¡Qué semana productiva! ¡Aprendí un montón!... Y es más ágil.

En el equipo en el que trabaja el monito de arriba no se programa de a pares, no hacen programación orientada al test, no se integra continuamente, no hay un representante del cliente en el equipo y no se elaboran historias del usuario ni se hace el juego de la planificación.

Pero al tipo le encanta XP (¡programadores al poder!) e intenta aplicarlo en todo lo que puede, porque es más ágil.

Usted, señor programador, que leyó hasta aquí con una sonrisa en los labios y con un ocasional "sí, es así, exactamente" en voz alta... usted, que seguramente le ha advertido al analista (que pasó frente a su escritorio en busca de un café) "tenés las horas contadas"... usted, gran orangután, es el peor de todos.

Porque es justamente usted, el programador, el que tendría que entender que no se puede pretender que un sistema funcione si le extirpamos arbitrariamente un pedazo de código y lo reemplazamos por otro que funciona bien... en otro sistema.

Porque seguramente usted se da cuenta de que así no funciona. Pero en vez de impulsar un cambio integral o buscarse un equipo más acorde a sus expectativas (o a su ansiedad) prefiere ser el engranaje que gira solo al doble de velocidad que los demás... muy ágilmente, por supuesto.

XP, como cualquier metodología, conforma un sistema. Cada punto de XP tiene una razón de ser dentro de ese sistema, no es una simple recomendación que "deberíamos" adoptar. Sólo por ejemplo: la codificación/diseño se apoya en la programación de a pares, que asegura que el diseño sea discutido al menos por dos integrantes del equipo. El refactory frecuente se apoya en la codificación orientada al test, ya que sin testeo automático es una actividad peligrosa. El minimalismo en la documentación funcional se apoya con la integración de un representante del cliente en el equipo al que se lo puede consultar continuamente, si no fuese así podría perderse mucho tiempo en la resolución de ambigüedades... todo tiene que ver con todo.

Por supuesto que hay que adaptar la metodología a cada caso particular. Y que sí se puede implementar parcialmente. Por ejemplo, sé que la programación de a pares es un punto usualmente resistido. Entonces, hay que compensar la no-adopción de esa práctica con algo... no sé, habría que probar. Podrían ser reuniones para fijar estándares de codificación, o revisiones formales del código, o una instancia informal de revisión del diseño... las posibilidades son infinitas. Tal vez algún comentarista con más experiencia en equipos XP pueda aportar un poco más sobre este punto.

Lo que queda claro es que la metodología es un sistema. Y, como a todo sistema, hay que conocerlo para modificarlo o adaptarlo, tomar esas modificaciones o adaptaciones con el debido cuidado, probarlas, etc... y no tomar frases sueltas para hacer mal lo que de todas maneras no había que hacer.

martes, 26 de agosto de 2008

Explicaciones (De dónde vienen los bebés).

Otro chiste aparecido en humor geek del estilo de Las confusiones de ahora....

La capa de acceso a datos.

A partir de los comentarios de la entrada "Jaque" me quedé dando vueltas alrededor de la arquitectura de la capa de datos en una aplicación.

El primer punto a definir es qué entendemos por capa de datos. Me gusta tomar Wikipedia porque siento que representa el mínimo común denominador entre todas las acepciones posibles. Una base sobre la que (creo) estaríamos todos de acuerdo. En la correspondiente entrada (Programación por capas) encontramos:

[...] Capa de datos: es donde residen los datos y es la encargada de acceder a los mismos. Está formada por uno o más gestores de bases de datos que realizan todo el almacenamiento de datos, reciben solicitudes de almacenamiento o recuperación de información desde la capa de negocio.

Lo que sigue a continuación es toda la secuencia de experiencia previa, análisis, pruebas y errores que nos llevó a la capa de acceso a datos que tenemos armada ahora, con la que estoy bastante conforme. Está claro que dependiendo del proyecto las atribuciones y responsabilidades de esta capa podrán variar sutilmente. Para el caso, necesito agregar una responsabilidad más, que puede o no asignarse a esta capa, pero que en todo caso quiero incluir en la discusión:

Transformar objetos que representan la estructura de la base de datos en otros que representan la lógica del negocio y viceversa.

Como decía, puede que se lo asignemos o no a la capa de datos, pero en lo que estaremos todos de acuerdo es en que los objetos que maneje la capa de negocios no deberían estar absolutamente condicionados por la estructura de los datos en la base, por más que tengan alguna relación con ellos o que utilicemos las tablas como punto de partida. Por ejemplo:

  • El módulo de facturación puede definir un objeto "Cliente" de acuerdo a sus necesidades, por ejemplo con una propiedad "Facturación" (una lista de facturas). Digamos que se llama "Facturacion.Cliente".
  • El módulo de CRM podría definir un objeto "Cliente" diferente ("CRM.Cliente"), más acorde a sus propias necesidades. Por ejemplo con una propiedad "Incidentes" que contiene una lista de las comunicaciones que tenemos con él.

Traducido a la capa de acceso a datos, estamos haciendo un JOIN entre la tabla de clientes y la de facturas por un lado y la de incidentes por el otro, más todas las tablas satélite que se puedan requerir en cada caso.

En el framework de trabajo existente hasta ese momento, cada objeto de negocio utilizaba una capa de datos para acceder a la base, pero definía su propia consulta utilizando el lenguaje específico, SQL, que se iba armando en el mismo objeto de negocio. La capa de datos devolvía objetos genéricos (DataTable, DataReader, etc.) que eran utilizados directamente. En este caso provee la persistencia y la conexión, pero se desentiende de la consulta en sí misma.

Los problemas más notorios son que el código de consulta ensucia la clase de negocio, no permite reutilización alguna y se producen infinitos puntos de acceso a datos. Por otro lado la utilización de objetos de datos genéricos como el DataTable hacen que el código sea difícil de seguir, sobre todo si se utilizan subíndices para acceder a los datos en particular (ej.: saldo=dataRow[1] + dataRow[3]).

Con este punto de partida, los primeros esfuerzos se orientaron a optimizar y ordenar el armado de esas consultas. En principio se adoptó una filosofía estricta de utilizar siempre procedimientos almacenados, para separar el código SQL del resto de la lógica.

Eso emprolija un poco el código, pero no resuelve los demás problemas. Era una tarea necesaria, pero que no atacaba el centro de la cuestión, representado por el ejemplo anterior: necesitamos manejar objetos de negocio específicos, no genéricos ("Cliente" en vez de "DataTable") y necesitamos acceder a propiedades evitando el uso de subíndices, entre otros.

Entonces comenzamos a armar una capa de acceso a datos que asumiera esa tarea de transformación de datos en conceptos de negocio, montado sobre el "proveedor de persistencia y conexión" (por llamarlo de alguna manera) existente.

Otro problema era lograr cierta reutilización. Estaba claro que si se creaba un procedimiento almacenado para cada necesidad estaríamos simplemente poniendo el muerto bajo otra alfombra. Todas la consultas que antes ensuciaban los objetos de negocio pasarían a formar un inmenso (e inmanejable) repositorio de procedimientos almacenados.

Aquí es donde entra en juego el problema de los JOIN en los procedimientos almacenados que se menciona al pasar en los comentarios de Jaque. En nuestro ejemplo, si hago un JOIN en la base de datos necesito dos consultas o procedimientos almacenados: una para Cliente-Facturas y otra para Cliente-Incidentes.

Algo similar sucede con las transacciones. Necesito grabar Clientes-Facturas en una única transacción. Si la implemento en un procedimiento almacenado, ese procedimiento sólo podrá grabar esa combinación de datos.

Era claro que por ese camino y sólo tomando las dos o tres tablas principales del sistema tendríamos una miríada de consultas diferentes, cada una respondiendo a una combinación cabecera-detalle diferente. Se descartó por ser a todas luces poco práctica la posibilidad de una súper-consulta que recupere (por ejemplo) un cliente y todos sus datos devolviendo una especie de súper-entidad. Está claro que la tabla cliente podría tener más de 20 tablas de detalle independientes (ej.: facturas, remitos, incidentes, pedidos, contactos, pagos, cheques, movimientos, y todo lo que se nos ocurra), y que rara vez se utilice más de un par en cada módulo de negocio (es claro que el módulo que maneje la chequera poco tiene que hacer con los incidentes). Por otro lado también se descartó la posibilidad de cargar esa súper-entidad "on demand" por presentarse demasiado compleja.

Es cuando surge como una posibilidad más sencilla el tener un conjunto de consultas estándar, las clásicas SELECT, INSERT, UPDATE y DELETE para cada tabla y con ellas llenar las estructuras de datos más complejas en el código. En la gran mayoría de los casos esto no representa problemas de rendimiento. Pero de todas maneras nada impide tener una consulta especial sólo para aquellas situaciones que sí lo justifiquen.

Surgieron así las clases de acceso a datos creadas automáticamente a partir de la estructura de cada tabla. Para nuestro ejemplo, tendríamos tres clases ya predefinidas: ClientesDatos, FacturasDatos, IncidentesDatos. El objeto de negocio las utiliza para llenar Facturación.Cliente.Facturas y CRM.Cliente.Incidentes en cada caso. Estas clases devuelven objetos tipados, también creados a partir de la estructura de las tablas.

Con las transacciones sucede lo mismo. Al momento de grabar un cliente y sus incidentes la clase de negocio abre una transacción, llama a las clases de datos correspondientes y la cierra. No puede abrirse una transacción en la misma clase de datos, ya que esto impediría la reutilización. Conceptualmente tiene sentido. Una transacción queda definida en la operación de negocio que se realice. No es lo mismo facturar que insertar un incidente, pero a la capa de datos no tiene por qué interesarle esto.

Pero estoy haciendo trampa, porque en mi ejemplo omití una situación común. Se puede argumentar, con razón, que IncidentesDatos devuelve, según mi ejemplo, incidentes para un cliente, y que probablemente otro módulo requiera, por ejemplo, "incidentes por responsable interno" o "incidentes sin responsable" o "incidentes no resueltos", etc. Para cada uno de estos casos deberíamos armar un procedimiento almacenado y estaríamos de vuelta con el problema anterior.

Esto era justamente lo que nos estaba comenzando a suceder. Si bien era fácil tener clasificados los procedimientos almacenados (ya que siempre se referían a una única tabla), la realidad era que por ese camino iban a ser demasiados.

Hubo que romper el mito de "todo procedimientos almacenados" (con cierta reticencia inicial por mi parte, pero por suerte la mejora se notó rápidamente, despejando las dudas). De vuelta a generar código automático, esta vez para crear objetos que encapsularan un criterio WHERE generado dinámicamente. Un especie de filtro extremadamente configurable para cada tabla.

La clave fue el encapsulamiento. Si la lógica de armar consultas "on the fly" se hubiese expandido sin control por todo el sistema estaríamos de vuelta en la situación inicial. Estos objetos (uno específico para cada tabla) se volvieron internos de la capa de datos.

Para resumir, en el cuerpo de un método de la capa de acceso a datos se crea uno de estos objetos, se lo configura con un par de líneas de código y al ejecutarlo nos devuelve un objeto tipado que representa los datos de una tabla de la base. Un objeto de la capa de negocio puede llamar a varios métodos de la capa de acceso a datos para crear objetos complejos según su necesidad.

Cambiamos procedimientos almacenados por métodos, que resultaron más fáciles de clasificar, mantener y controlar. Un ejemplo en este sentido: si cambio la estructura de una tabla y genero automáticamente el código de la clase de filtro para esa tabla, se provoca automáticamente un error de compilación en todos los métodos de datos que se vean afectados por el cambio (y sólo en ellos). Una vez arreglados estos errores de compilación puedo estar seguro de fue implementado sin mayores consecuencias. Es decir, si compila funciona, si no funciona no compila.

¿Y dónde quedaron los JOIN y los procedimientos almacenados en T-SQL? Reservados sólo para algunos casos especiales, donde la consulta se realiza sobre tablas muy grandes o donde es necesario alguna lógica adicional u optimización relacionada con los datos. Pero resultaron ser apenas un par de casos excepcionales.

lunes, 25 de agosto de 2008

The Photoshop Challenge

Recién salidito de Punto Geek (vía NiceFuckinGraphics) este test en el tendremos que decidir cuáles de las 30 imágenes que se nos presentan estan "photoshopeadas".

Photoshop Quiz
Created By Their Toys

Como verán no me fue muy bien.

Atari

Para aquellos que se han sentido identificados con la entrada Nostálgico, este post de Microsiervos consigna dos artículos biográficos sobre Atari:

domingo, 24 de agosto de 2008

Asteroides

La Nube de Oort es una nube de cometas que se cree se encuentra en el límite del Sistema Solar, a una distancia aproximada de 100.000 UA ó 1 1/2 años luz del Sol. Se ha calculado estadísticamente que puede haber entre uno y cien billones (1012 – 1014) de cometas. [...] El efecto gravitatorio de las estrellas próximas desvía a los cometas de sus órbitas y los envía hacia el Sol, donde se vuelven visibles.

Wikipedia - Nube de Oort

Todo ambiente de desarrollo está rodeado de una nube de requerimientos suspendidos en delicado balance en los límites del negocio. Algunos son conocidos, la mayoría no. De vez en cuando alguno de ellos cae y debe ser manejado de alguna manera. Léase esquivado o absorbido por uno o varios integrantes del equipo. De tiempo en tiempo una gran perturbación en esta nube, una explosión o el paso de alguna mala estrella puede provocar una verdadera lluvia de estos objetos.

Tal ha sido el caso de la semana pasada. En principio apareció un cometa de polémicas dimensiones. Desde el punto de vista del líder de proyecto, apenas una simpática piedrita que aparecía para decorar el firmamento por un par de horas. Desde el punto de vista del líder técnico y de uno de los integrantes de más experiencia, un asteroide amenazador que avanzaba en picada siguiendo un peligroso rumbo de colisión hacia lo más delicado de un sistema ya bastante golpeado.

Como muchas veces sucede, nos fuimos enterando de las verdaderas dimensiones y características del objeto cuanto más cerca estaba de nuestras cabezas. Resultó ser de esos que luego del primer impacto esparcen peligrosas esquirlas por todos lados.

Yo observaba la escena desde una distancia prudencial. Tenía algunos pequeños asteroides propios que destruir y me entretenía en ello, levantando de vez en cuando la mirada para ver pasar alguna de estas piedras convertida en estrella fugaz. Lindo despliegue.

Así, distraído con el espectáculo principal, no noté el acercamiento de un pequeño asteroide que se aproximaba dando tumbos, rebotando de aquí para allá, sin decidirse a adoptar un rumbo fijo.

La primera vez que lo ví ya había impactado en mi escritorio, dejando un pequeño cráter rodeado de una nube de polvo. Era un reporte.

Hacer reportes tiene sus bemoles. Uno de vez en cuando es divertido. Hay que investigar el negocio para ver cómo se consiguen los datos. Esta parte me gusta, aparecen complicadas relaciones entre un sinfín de tablas y cálculos extraños que hay que resolver con algo de ingenio. Luego, a jugar con SQL. Y aquí se acaba la gracia. Porque una vez que uno tiene la consulta la cosa está cocinada, no hay mucho más que pensar pero... no alcanza con ello. Hay que hacer el reporte.

Y aquí empieza: que dos cuadros separados por algún criterio que no es el más cómodo para obtener los datos, luego que no me entran los datos en la página, luego alinear un sinfín de columnas, luego que la columna "cantidad" me aparece con decimales... y cuando ya tenemos una miríada de detalles menores resueltos... "no, mejor esta columna la pasamos acá" y de vuelta a alinear y reacomodar. La herramienta que manejamos (Crystal Reports, por una situación de muchos "legacy reports"), si bien es completa, de vez en cuando se tara de mala manera (usualmente con un detalle nimio pero que "no puede quedar así") y nos roba un buen par de horas fuera de agenda.

Viendo entonces que el objeto era un reporte, soplé un poco para apartar la nube de polvo y ver la definición... me encontré con un par de instrucciones SQL. Mmmmmm.... ¿qué es esto? Esperaba más bien un documento o una hoja garabateada que indicara el formato y algún ejemplo.

La intención era clara. Estos son los datos, hay que armar el reporte. Ajá. Me acordé de División de tareas, donde citaba proféticamente:

Vos vení con problemas y yo te doy soluciones. Si me venís con soluciones, te voy a dar problemas.

Dicho y hecho. Me había caído no un requerimiento sino una solución. Y como toda solución, tenía sus problemas.

En principio no abarcaba el formato del reporte. Este dato vino en la forma de otro asteroide proveniente de un sector diferente de la nube que no guardaba relación aparente con el primero. Así que había que ajustarlos, ya que no encajaban.

Para seguir se volvió claro, luego de un par de minutos de trabajo, que tenía ante mí un boceto de alguna intención que yo podía más o menos entrever intuitivamente. Pero tenia algunas contradicciones respecto de algunas partes del negocio que yo conocía. Esto también había que resolverlo.

A esta altura del partido he aprendido a reclamarle peras al olmo constantemente (casi por deporte), pero sin quedarme sentado a esperarlas. Es divertido ver todo lo que se puede avanzar a ciegas. Hice bastante (a mi entender) sin saber demasiado bien qué era lo que estaba haciendo. Un poco de olfato, un poco de oficio, bastante de saber a quién preguntar dónde buscar. Trabajo detectivesco.

Pero por más garra que uno le ponga, en algún momento iba a ser necesario entender hacia dónde me dirigía. Tres o cuatro días después de empezar, ya un poco cansado, logré entender qué estaba haciendo. Es decir, logré que me explicaran, de-una-forma-en-la-que-yo-pueda-entender (sí, soy un poco lento) el objetivo del negocio, el concepto detrás de esos datos.

Sólo para darme cuenta de que a la luz de este objetivo se percibían dos o tres "pequeños detalles menores" a corregir (irónico, por si no lo notaron), que al fin y al cabo el requerimiento no era tan complicado de expresar y que si lo hubiese tenido desde el principio no me hubiese costado tanto.

En resumen, intenté ir desde un boceto de solución hasta el requerimiento original, por supuesto que no lo logré, finalmente me lo explicaron y con ello corregí lo que había hecho hasta llegar a una nueva solución. Que no creo que esté del todo bien, pero por lo menos ahora es contrastable con respecto a ese objetivo y por lo tanto corregible.

Por ahora los dejo masticando la anécdota de la que creo que pueden derivarse varias cuestiones teóricas... va para otro post. Habría que redondear un poco más lo siguiente: hay un montón de blogs de desarrolladores contando anécdotas quejosas más o menos parecidas, con mayor o menor gracia. Por otro lado tengo un buen par de blogs donde se discuten las famosas "cuestiones teóricas"... rara vez se cruzan estos dos enfoques.

Actualización: La historia continúa en Requerimientos: cuando no son asteroides sino sólo polvo cósmico.

sábado, 23 de agosto de 2008

Curiosidades en el baúl de la abuela.

Me encontré por casualidad con este post de Softhoy sobre Microsoft bob, un engendro del que nunca había escuchado hablar, y del que ahora descubro todo un mundo con olor a viejo.

viernes, 22 de agosto de 2008

Enojado con uds.

¿Es que nadie va a decir nada sobre el nuevo formato del blog?

No me vengan con eso de "yo lo sigo por el feed".

¿O es que nadie me lee (más que probable)?

¿O es que nadie se preocupa por mis sentimientos (snif)? ¿Saben el tiempo que pasé eligiendo los nuevos colores porque a alguno se le ocurrió decir que el negro dificultaba la lectura (ah, para criticar sí hay palabras)? ¿Y tratando de entender las plantillas de Blogger (hay más que lo que documentan, malditos)? ¿Y acomodando esas dos columnas de m...? ¿Y tratando de hacer que desaparezca la barra de desplazamiento horizontal (maldito div vacío)?

Clasificando mi spam (I)

Nunca veo demasiado mi spam. Usualmente lo consulto una vez al día y lo borro, con lo cual ni siquiera sabía cuánto me llegaba.

Bien, como tengo muchas otras cosas que hacer, y para variar ninguna gana, me he puesto a clasificarlo. En principio los dejé acumular un par de días. Luego tomé los últimos 100 mensajes, que han venido a ser los últimos 3 días. Así que recibo unos 30 por día, aproximadamente. Bastante poco, según creo.

Categorizarlos ha sido realmente sencillo, se ve que recibo de unas pocas fuentes que envían varias veces al día, ya que son todos muy similares.

Vamos a los resultados:

jueves, 21 de agosto de 2008

Pobre XML...

En los últimos días se le estuvo pegando bastante a XML en este blog.

Primero fue XML * Inconciencia, donde referenciaba un post de Lucas Ontivero con malas prácticas y delirios malos con XML.

Luego fue XML donde citaba "XML is like Violence, if it doesn't solve the problem, use some more".

Y encima estoy preparando un post sobre mi propio aprendizaje de XML, que se dio a través de la construcción de una aplicación web que almacenaba sus datos enteramente en XML... muchas frases en el estilo de "estaba aprendiendo" y un alto contenido de "mea culpa".

A ver, XML es una herramienta fabulosa, fácil de entender (casi intuitivo si uno viene del viejo mundo HTML), popular (con mucha documentación y herramientas disponibles), ampliamente utilizada (es *EL* estándar para intercambio de información entre aplicaciones) y sobre todo flexible.

Lo mismo que Javascript, ASP 3.0, PHP... antes de saltarme al cuello déjenme explicar qué les veo en común todos estos lenguajes: en todos ellos, sobre todo cuando se los ve junto a HTML o XML, es frecuente el abuso de alguna de sus características, sobre todo de aquellas que nos permiten esquivar rápidamente los tipos de datos o que tienen que ver con la ejecución de código generado "on the fly", o con el pasaje de datos del servidor al cliente, en divertidísimas combinaciones.

Creo que para muestra basta un botón. El ejemplo es una hermosa combinación de ASP 3.0, HTML y Javascript (¡qué lindos colores!). Lástima que no se me ocurrió generar XML embebido en la misma página.

El problema no está en la herramienta sino en cómo es utilizada, sobre todo en manos de un principiante (el código de ejemplo es mío, así que créanme que sé de lo que hablo). Como no me canso de repetir, ser un "junior" no implica solamente el manejo de una herramienta. Para el caso, en el momento en que escribí eso (que podemos llamar... un colorido desastre) tenía bastante idea de HTML, ASP y Javascript, pero no tenía la más mínima idea de cómo construir una capa de presentación en una aplicación web medianamente compleja, con lo cual terminé abusando de todo lo que sabía.

Uno puede saber todo sobre XML, pero se necesita bastante práctica para crear un documento coherente. Como la herramienta nos permite hacer casi cualquier cosa, estamos librados a nuestro criterio al momento de producir algo legible, que dependerá de nuestra comprensión teórica del modelo: ¿cuándo un dato es un atributo? ¿cuándo debe ser un nodo? ¿cuándo tengo que englobar varios nodos en un nuevo nivel?

También se necesita práctica para saber cuándo parar. Con XML podemos hacer de todo, pero eso no significa que debamos hacer de todo. En los post que mencionaba al principio se menciona el caso del sistema con una tabla única con dos campos del tipo "ID" y "XMLData" en el que se guardaban todos los datos de la aplicación. A ese tipo de cosas me refiero cuando menciono "saber cuándo parar".

Ésas no son preguntas fáciles de responder, y los programadores con poca experiencia tienden a subestimar las consecuencias, argumentando que son "bla bla bla teórico" y que "de cualquier manera funciona"... Algunos programadores con mucha experiencia piensan lo mismo, desgraciadamente. Son los que Rafael Gil en un momento de inspiración nombra "Programadores Romario" en su blog "Diario de un Director de sistemas".

Creo que el título XML * Inconciencia es perfecto. El problema es la inconciencia. De alguna manera todo el mundo reconoce que diseñar una base de datos es difícil, y que un error puede tener un serio impacto a futuro, así que en general se le presta la debida atención. Esto no sucede tan seguido con el XML (aunque diseñar un documento es prácticamente lo mismo que diseñar una base de datos), hay casos en los que se supone que es una herramienta sencilla y fácil de usar que nos puede sacar de apuros y que no merece mayor análisis. Termina siendo una navaja nueva para un monito aburrido.

En algún otro post comentaré con más detalle los casos en los que sí se utilizó XML razonablemente con muy buenos resultados, por ahora simplemente una lista:

  • Para archivos de configuración de la aplicación del tipo "web.config" o "app.config". Son el equivalente a los viejos archivos ".ini". La ventaja es que el XML documenta muy bien las secciones y los valores que puede tomar cada parámetro.
  • Para guardar datos que hacen a la estructura de la aplicación. Por ejemplo la relación entre página-controlador en un patrón MVC.
  • Para guardar parámetros por defecto que necesita la aplicación.
  • Como alternativa a los archivos de recursos (del tipo ID+Cadena) cuando se necesitan almacenar datos complejos.
  • Por supuesto, para intercambiar datos entre aplicaciones. Pero con cuidado, no puede ser gran cantidad de información (XML es muy ineficiente en cuanto a tamaño) y, sobre todo, que sea simple: descargo a un archivo la información (o cualquier equivalente) y punto.

Dos puntos importantes:

  • Mantener siempre actualizada la documentación sobre la estructura del archivo. Si es un XSD o un DTD, mejor. Si la aplicación lo valida al levantar los datos, perfecto.
  • Siempre encapsular el archivo en una clase que devuelva los datos tipados al resto de la aplicación. Es fácil, no cuesta nada, mucho más cómodo que buscar todo el tiempo en XML (por ejemplo utilizando XPath en todos lados) y encima ahorra un montón de problemas a futuro, permitiéndonos cambiar la estructura del archivo prácticamente sin impacto.

Como conclusión: XML es grandioso. Pero, como toda herramienta, no puede ser utilizada a la ligera. Es tan fácil y divertido como buscar un poco en Google antes de empezar.

miércoles, 20 de agosto de 2008

Más antipatrones.

José M. Aguilar publica un muy buen resumen de antipatrones en esta entrada de Variable Not Found. Por otro lado, hace un par de meses yo había traducido algunos que no encontraba en castellano (un poco más en joda) y los había posteado en Antipatrones de diseño.

Vía Cerebrado (muy despierto hoy, vamos a desenchufarlo un rato).

Versionado maloliente (El arquitecto negador).

En este blog han salido castigados programadores, analistas, líderes de proyecto, usuarios... pero hay un participante del proceso de desarrollo al que no le he señalado ninguna falta (¿por qué será?)... el arquitecto de software.

El arquitecto es como un programador que piensa mucho, que ha programado muchísimo pero que ya no no lo hace demasiado y cada vez menos (a veces extraña). Su trabajo es más bien crear una estructura más o menos vacía que el resto del equipo irá completando con el conocimiento del negocio.

De esta manera, alejado del barro y el polvo de la obra en construcción, se mantiene impoluto mientras controla el avance.

En parte es cierto. Pero la arquitectura de software tiene su barro. Aparte de pensar y crear bonitos esqueletos el arquitecto tiene, entre otras cosas, que hablar con el líder de proyecto (o que soportarlo, o esquivarlo, depende el día), pelearse con analistas (con o sin razón), sufrir porque sabe que no llega "ni a ganchos", mirar el código y amargarse (porque es un obsesivo), llevar el versionado y el mantenimiento y organización general del sistema de control de código fuente, entre otras edificantes tareas.

Tarea ingrata esta última si las hay, sobre todo en un equipo donde hay muchos proyectos (que a veces nacen y crecen como hongos, de la nada y de cualquier manera), muchas cabezas organizadas de formas diferentes (todas ellas válidas) y en especial... muchas versiones. Esto último dependerá del negocio. En algunos negocios uno sabe con meses de anticipación la fecha de lanzamiento de una versión. En otros puede darse un viernes a las cinco de la tarde... con suerte se gana tiempo con un tímido "para el lunes".

Versionar y organizar es ingrato, repetitivo pero más o menos esporádico y muy susceptible a errores complicados de detectar y más aún de resolver.

Un error de diseño en un buen arquitecto es cosa de todos los días. Al fin y al cabo es un error de diseño, que si en general es bueno se compondrá con relativa facilidad. Un error de versionado... es más complicado de corregir, pero es un error aceptable. Lo mismo que al codificar, siempre se comete algún error (por minúsculo que sea) al versionar. Para eso se prueba.

Un error de procedimiento al organizar el versionado o el control de código fuente... es más duro de tragar. No es una distracción, no es un pequeño error en una larga serie de pasos... es el equivalente del rubro a ese código tan feo que al arquitecto le encanta debatir y enmendar o someter al escarnio público en blogs como éste (y que a todos les gusta ver, síndrome de "not in my code", que le dicen, o algo medio morboso que tenemos algunos programadores).

Porque hay veces en las que el arquitecto tiene que meter la mano en el barro, dar vuelta carpetas y proyectos que no tiene la menor idea de qué tienen adentro y rezar por que todo haya salido más o menos bien, ya que no puede probar todo eso y mucho menos decirle a nadie lo que acaba de hacer.

Como siempre Cerebrado es el mejor a la hora de proponernos situaciones "muy cercanas a la realidad", como la siguiente charla entre programador (P) y arquitecto (A). Vamos a repetir la exitosa fórmula de "Simpleton (un post a cuatro manos)", pero ahora escribe él y las itálicas son mías:

P (programador): -Moviste las carpetas del framework en el SourceSafe, nadie nos avisa nada y a nosotros nos quedan enlazadas las soluciones de nuestros proyectos a cualquier lado.

El tipo quería reorganizar eso a sabiendas de que necesariamente iba a dejar algún cabo suelto, pasó un tiempo y... nada, pensó que había zafado. Arma rápidamente una estrategia: negar.

A (arquitecto): -Si, pero me encargué de abrir todos los proyectos que referencian al framework y actualizarlos.

Es decir... bueno, los que el creía que referenciaban al framework de la manera en que deberían referenciarlo... suponiendo que todos hayan sabido hacer eso en su momento... al fin y al cabo él no es el encargado de asegurarse de eso... bueno, tal vez sí es el encargado, pero la vida del arquitecto es muy complicada.

P: -(¡¡WTF!!) Este... pero eso lo podés hacer cuando son pocos proyectos...

A: -¡Claro! Si todavía son pocos, creo que no más de 10. Te los puedo decir de memoria: (tira dos o o tres)... (carraspea)... ejem...

Aquí ya se empieza a dar cuenta de que metió la pata no una sino dos veces. La primera era inevitable, algún cabo suelto iba a quedar. La segunda pudo haberse evitado. Tendría que haber respondido "sí, ya sé, pero tenía que reorganizar eso y no quería armar un debate, a medida que encontremos los errores los voy corrigiendo, no está muy bien, pero por lo menos lo vamos ordenando". Amor propio, qué mal consejero. Estrategia alternativa: negar, negar y negar.

P: -Yo te puedo nombrar al menos 3 proyectos que vos ni sabés que existen.

A: -¡Pero eso está mal! ¡Me estás diciendo que hay 3 proyectos que andan dando vueltas por ahí y yo que soy el arquitecto no los conozco!

Un poco de distracción, de arena en los ojos, tal vez la charla deriva a esos problemas de comunicación tan frecuentes... Tiene razón, pero los proyectos estaban ahí, en **SU** control de código fuente.

P: -De acuerdo, está mal... pero también está mal que vos toques cosas que nos pueden afectar a todos y no informes de esos cambios.

A: -No está mal. Yo me hago responsable de lo que hago.

Avisar ¿yo? Si hago 10 refactories por día y nadie se entera porque el diseño (que es una obra de arte) lo permite. Tendría que haber pasado lo mismo con el movimiento de carpetas. Si hubo algún error es porque algo (que no es mi estructura) estuvo mal armado (es decir, no estuvo igual a mi estructura). La estrategia va bien. Sigamos con el plan: negar.

P: -Está bien que te hagas responsable, pero está mal.

A: -No.

Casi zafa, no va a dar el brazo a torcer... sólo hace falta negar un poco más.

P: -Sí.

A: -No.

P: -Sí.

A: -No porque blah blah blah (hace uso de su fantástica labia).

Saca las reservas: fundamento teórico, de ese que siempre dice que "hay que acomodar a la situación". Bueno, es verdad, éste es el preciso momento en el que el andamiaje teórico se acomoda a la situación... de nuevo.

P: -Sí.

Está pensando "Maldito programador obstinado... el tema es que éste ya olió sangre, no me va a soltar".

A: -Bueno, sí está mal, LO HACES IGUAL, porque en mi equipo somos n y hacemos ésto desde el principio, y estamos todos de acuerdo y (mas blah blah blah).

Es decir, la tuya "es una opinión y es válida"... pero acá mando yo. Y ya no voy a dar el brazo a torcer porque admitir que me equivoqué ahora es admitir que vengo negando como un nene al que lo descubrieron con la mano en la lata. Estrategia de refuerzo: negar negar y negar (cuando sólo tenemos un martillo todos los problemas son clavos).

P: -Ah (coma caca, millones de moscas no pueden equivocarse...).

A: -Lo que pasa es que para trabajar en equipo a veces en las que hay que acatar.

Argumento irrefutable que no se aplica a este caso (ya que el programador nunca hizo nada en contrario de nada, sólo cuestiona).

P: -Mirá que buena que está esa flaca...

A: -Uh, me la perdí.

Y como no se puede razonar un argumento basado en el autoritarismo, el programador prefiere hablar de mujeres. Al fin y al cabo conoce al arquitecto desde hace un tiempo y sabe que cuando se enoja es que sabe que no tiene razón.

Historia de un Euro

Por si alguien no lo ha visto ya o se le pasó de largo, paso el link a Historia de un Euro, donde Maikelnai (qué buen nombre) relata la historia completa del hallazgo de la moneda.

Vía Microsiervos.

martes, 19 de agosto de 2008

Actividades informáticas vs. olímpicas.

Voy a reconocer que el post Trivia olímpica informática del blog "Mi carrera laboral..." me pareció en principio una soberana estupidez ("con la mejor onda, ¿eh?"), sobre todo porque los ejemplos no eran de lo más divertido.

Pero ahora veo que por suerte los lectores han superado a los redactores, con algunos comentarios muy buenos:

  • Uf! Trabajando en seguridad informática solo puedo sentirme un referí.
  • Subgerente de sistemas - 100 metros con vallas. Vive saltando obstáculos con tal de llegar a la meta.
  • Gerente general == Espectador. Se entretiene viendo al resto trabajar, jaja

Y hay bastante más... a mí todavía no se me ocurre ninguno.

Jaque.

Hace un par de días descubrí el muy prometedor Un Punto Azul Pálido. Empecé a leer hacia atrás, hasta darme con la entrada El objeto del negocio donde el autor despotrica contra los métodos de negocio "inútiles" al estilo public void almacenarCuenta(Cuenta c) { cuentaDao.almacenar(c); }

Donde se ve una capa de negocio inútil que hace de pasamanos entre el front-end y la capa de datos, sin aportar nada.

Alguna parte de la aplicación sobre la que trabajo está así. "Jaque", pensé, porque por un lado no podía dejar de estar de acuerdo con lo que había leído, pero por el otro mi orgullo, un poco herido, quería salir a defender la estructura que armamos (es un proyecto que comenzamos de cero absoluto) y que ha probado ser más que robusta, legible y escalable (en serio, lo ha probado).

Logré dejar el amor propio de lado (sentimiento dañino si los hay para un desarrollador, que debe estar siempre consciente de que **nunca** ha escrito código sin errores), pensé un rato y me dí cuenta de que en realidad el post critica algo que nosotros mismos ya nos hemos criticado y conversado, por lo que creo que es interesante contar un poco cómo es que sucedió eso y, sobre todo, advertir que si bien no está bien que esto suceda, podría ser peor.

El requerimiento (absolutamente paperless) era crear un framework de trabajo, y al tiempo desarrollar la nueva versión de la aplicación principal de la empresa reescribiéndola desde 0. Cambio de tecnología (de .Net 1.1 parecido a VB 6 a .Net 2.0), de lenguaje (de VB a C#) de paradigma (de estructurado + orientado a formularios y eventos a orientado a objetos) y de entorno (de aplicación de escritorio a aplicación web para correr en un servidor de la intranet).

Entonces, teníamos que "copiar funcionalidad" (producir la misma salida que antes en pantalla y contra la base de datos) con la aplicación existente como única referencia. Ésta contaba con poca documentación y tenía el código enmarañado por el mantenimiento y el rápido crecimiento. Por otro lado el equipo estaba muy fresco, recién habíamos entrado a la empresa y no teníamos la más mínima idea de un negocio que para colmo de males es bastante particular.

Encima se sucedieron algunos cambios de asignaciones y finalmente de personal (todo tranquilo, nada terrible). Finalmente quedamos dos "arquitectos". Yo en realidad tirando un poco más para el lado de la aplicación o el negocio. Así que el otro empezó desde más abajo en la arquitectura, yo desde la capa de datos hacia arriba.

Cuestión que después de un tiempo la capa de datos quedó muy bien armada utilizando un generador de código, con la que creamos una clase encargada de cada tabla más algunos artilugios.

Llegamos al punto. El negocio. Nuestra agenda se basaba en reproducir "pantallas" de la aplicación anterior. Pero no teníamos un inventario de las funcionalidades que involucraban esas pantallas. En todo caso, esta forma de ver la aplicación (como un conjunto de pantallas independientes) se basaba en una filosofía que no era la nuestra (patrón MVC, con una controladora por funcionalidad, que puede vincular una o muchas páginas a uno o varios objetos de negocio).

Resumen: teníamos la estructura armada para el MVC, teníamos la estructura para la capa de datos, teníamos la estructura general del front-end armada... y faltaba diseñar la capa de negocio... de un negocio que no sabíamos muy bien de qué la venía.

Y ahí metí la pata. Sí, metí la pata. Con el generador de código creé una clase de negocio inicial a partir de cada tabla de la aplicación. Pasamanos. Un montón de pasamanos.

Tres errores conceptuales, por lo menos:

  • El principal: un negocio no se automatiza, se piensa, se diseña. Nadie nos salva de eso, hay que tener cuidado con las soluciones mágicas. El negocio es la parte de la aplicación en la que ninguna herramienta puede reemplazar a un ser humano, y en la que ninguna regla automática nos va a venir a salvar. Hay que relevar y entender el negocio antes de meter los dedos.
  • Vincular conceptualmente el negocio a la estructura de la base de datos. Es casi el mismo error que vincularlo conceptualmente al front-end. El negocio es el negocio, por eso es una capa separada. Si lo vinculamos a la base de datos caemos en la estructura pasamanos, si lo vinculamos al front-end caemos en la siempre terrible, enmarañada y cambiante lógica del usuario.
  • Reprodujimos una lógica que no era la nuestra (la del sistema viejo) sin conocerla a fondo. Nos "comimos" todos sus errores conceptuales al no diferenciar lo que estaba bien de lo que estaba mal. No vimos sus puntos fuertes. No utilizamos la experiencia. Copiamos.

Pero, dentro de todo, algunos aciertos:

  • Algo había que hacer, y se respetó la máxima de los principios de diseño: "más vale disperso que denso". Con el tiempo muchos pasamanos se fueron llenando de código: de validaciones, de relaciones, de métodos y clases complejas. Se creó mucho espacio vacío e inútil, pero la mayor parte de ese espacio terminó siendo esencial para colocar código que sabíamos que iba a estar pero que en ese momento no sabíamos cuál era. De esto adolecen los ejemplos en el código mencionado arriba. Ok, el método simplemente toma los datos y los graba a ciegas. ¿Pero no tiene que validar nada antes? ¿No tiene que presentar mensajes al usuario en caso de problemas de negocio ("El movimiento no se puede insertar porque el cliente no tiene saldo suficiente")? ¿No tiene que verificar que el estado del sistema sea válido para la operación? ¿No tiene que revisar los permisos del usuario actual? ¿Dónde está esta funcionalidad? Si la operación impacta en varias tablas ¿no tiene que iniciar una transacción? Creo que debería estar ahí. Supongo que el problema de la aplicación que describe el post de Improbable es que ese código no está, y por eso el método está vacío. ¿Dónde lo habrán puesto?
  • Con esta "salida" la capa de datos quedó oculta, inaccesible (internal de la librería de datos+negocio) y esto es importante. El front-end no debe acceder a datos directamente. El pasamanos actúa al menos como un encapsulador de la capa de datos donde podemos ubicar código de ser necesario. Si no hacemos nada es peor, ya que tendremos muchas páginas o elementos del front-end accediendo cada uno por su lado a los datos. Un cambio en la estructura de una tabla impactaría directamente en el front-end, y no habría un lugar donde frenar ese impacto.
  • Fue corregible, fue mantenible. Fuimos haciendo refactorizaciones. Borramos algunas clases. Fuimos metiendo unas en otras que se convirtieron en internas y así se presentaron objetos y métodos más complejos. En esto fue fundamental el uso del patrón MVC que frenó los cambios, que no impactaron en el front-end (que se desarrollaba en paralelo), detalle sutil que los hizo posibles. Creo que si hubiésemos vinculado el negocio al front-end hubiese sido imposible "bajar" la complejidad adquirida.
  • Representó en su momento lo poco que conocíamos del negocio: la estructura de la base de datos. Es importante que la estructura de un proyecto represente lo que los desarrolladores saben de él. Lo vuelve legible. A medida que aprendíamos más del negocio, lo íbamos modificando. Nunca tuvimos documentación funcional, y todavía (con varios módulos desarrollados) no nos perdemos. A veces no sabemos qué hay que hacer, pero por lo menos es fácil saber qué fue lo que hicimos.
  • No repetimos el error: cuando hubo que incorporar un nuevo módulo, hicimos el relevamiento correspondiente a partir del sistema viejo y repensamos y rediseñamos el negocio de acuerdo a las virtudes y a los errores que vimos. Es decir, aprovechamos la experiencia del sistema anterior, cosa que antes no habíamos hecho.

En resumen, lo que rescato:

Hay que pensar el negocio, no queda otra.

Pero si estamos apurados, es preferible crear objetos de más (pasamanos) que enmarañar todo.

Está bien salir del paso, pero no debería quedar así. Hay que ir depurando lo que sobra a medida que se dan los cambios.

Para finalizar, creo haber salido del Jaque aunque con alguna pieza de menos, veremos cómo sigue.

lunes, 18 de agosto de 2008

Juegos filosóficos: Staying Alive

¿Qué significa permanecer con vida?

En The Philosophers' Magazine podemos descubrir nuestra propia respuesta. El resultado es más que interesante.

XML

Una frase rescatada de los comentarios de la entrada Worst Practices... del blog de Tom Kyte.

XML is like Violence, if it doesn't solve the problem, use some more.

No puede ser más cierto, y tiene mucho que ver con el contenido de la entrada XML * Inconciencia que publicaba acá hace unos días.

Actualización: pueden descargar la presentación de Tom Kyte a la que se refiere el post y que menciona el comentario de Improbable aquí (el link del post original está roto).

domingo, 17 de agosto de 2008

Fracase ya!

Una muy buena guía rápida para líderes de proyecto que quieran fracasar velozmente: Diez consejos para fracasar ahora en su proyecto.

Por ejemplo:

  • Si te estás comunicando no estás haciendo cosas, por lo tanto, comunicarse es perder el tiempo. Por otro lado usted no tiene nada que escuchar ni del cliente ni del equipo, si fuesen tan listos ya serían PMs.
  • Documente lo menos posible, la documentación lo compromete y hasta puede que quede en evidencia el estado de su proyecto.

Vía Cerebrado.

P.D.: es divertido que aunque no todos están tan apurados como para cumplir con toda la guía, ninguno se priva de anotarse en algún puntito... y bueh, nadie es perfecto.

¡Así se responde a una amenaza legal!

Respuesta a una amenaza legal por parte de Dreamworks a PirateBay.org, en esta entrada de Nulleando (vía... un largo etcétera, que no pienso reproducir).

Un botón de muestra, para que vean cómo viene la mano:

It is the opinion of us and our lawyers that you are ……. morons, and that you should please go sodomize yourself with retractable batons.

Y si siguen los links hay muchas, muchas respuestas más.

sábado, 16 de agosto de 2008

El punto singular.

Un tema para seguir hasta el infinito: la singularidad tecnológica, que

[...] es el hipotético momento donde las computadoras se harán inteligentes y conscientes de sí mismas [...]

(extraído de la entrada El punto singular del blog de Improbable, un muy buen lugar para hacerse de un primer pantallazo y comenzar a bucear).

viernes, 15 de agosto de 2008

¡Se cayó el sistema!

Sigo robando del reader de Cerebrado y de Lucas Ontivero (pero con link, al menos).

Esta vez para rescatar un post medio viejito, Se cayó el sistema.

Me quedan en la cabeza las últimas frases: ¿por qué nunca "Se perdió el balance" o "Se trabó la bóveda"?

Estimando.

En Comunica... ¿QUÉ? me planteaba que debería, como programador, leer más blogs de líderes de proyectos y analistas, para tener una mirada diferente del proceso de desarrollo.

Pues manos a la obra y ya tengo en mi reader un par de blogs más que interesantes. Poniéndome al día en ellos, encontré este intercambio de ideas (discusión, bah) que comienza con Planning Poker distribuido por Rodrigo Corral, sigue en los comentarios de esa entrada, segundo round en la entrada Estimaciones Agiles, no Extremas de Lucas Ontivero y final (ya un poco salida de sus cauces) en los comentarios.

Antes que nada aclaro que es mi idea dar una opinión más desde la experiencia que desde lo académico, ya que considero que he leído lo mínimo y ni siquiera me atrevo a citar por miedo a quedar en ridículo. Pero bueno, he estimado bastante solo y en grupo y obtenido una amplia gama de resultados.

Definitivamente el método de estimación debe ajustarse para cada equipo y situación en particular. Eso no impide pensar en algunas generalizaciones:

Los argumentos derivados de la "participación de todo el equipo en la estimación" que vuelve al proceso "más democrático" en general me hacen un poco de ruido.

En principio porque adhiero al concepto general de "la solución más simple es la mejor". En este caso, para decirlo crudamente, "cuantos menos monos y navajas haya en la fiesta mejor". Esto no implica ignorar diferentes voces ni desechar aquellas con las que no se está de acuerdo, pero de todo el equipo deberían participar en las reuniones la menor cantidad de integrantes que permita llegar una estimación razonable. A mayor cantidad de participantes los tiempos de reunión y discusión crecerán exponencialmente. La estimación mejorará, es cierto, pero a partir de cierto número sólo en forma ínfima.

Y está el tema de la "democracia" y la "participación". Un equipo de desarrollo no es una democracia, el que crea estar en una vive engañado. El objetivo es estimar, no ponerse de acuerdo ni hacer que el personal se sienta motivado (hay mejores formas de lograr esos objetivos que levantar tarjetas numeradas). La participación real se acota a las personas que el líder juzgue relevantes (esto anula lo de la democracia), y en definitiva él tendrá la última palabra. Pueden haber 10 personas en la reunión, pero tal vez él presta verdadera atención a dos o tres (imaginemos en qué planeta puede terminar su cabeza si se discuten detalles técnicos), y en este caso ¿para qué están las otras?. Por algo lleva la responsabilidad (si no la tiene no es el líder, no importa lo que diga su tarjeta). En última instancia, estos juegos participativos multitudinarios le servirían más para diluir sus culpas (e incluso de eso dudo, de cara a un cliente) que para llegar a la estimación.

Deberíamos confiar en que los que participen en la elaboración de los tiempos consulten con algún otro integrante los temas puntuales cuando sea necesario. Deberían exponer luego los resultados al resto del equipo o se podría requerir una última revisión formal por parte de todos (pero cada uno revisando su copia de la planilla por separado y anotando sus dudas).

Una solución de ese estilo permite una reunión más parecida a una charla que a un complicado ejercicio rodeado de un sinfín de reglas, elementos medio ridículos, idas y vueltas: que te saco, que me quitás, que la tarjeta, que paso, aumento, doblo y cuánto me das por un par de pantalones (quisiera saber qué es lo que hace el jefe con las reglas cuando la cosa no avanza). No hay como la comunicación informal y entre 6 o 7 personas es imposible mantener una línea.

Un punto más: si haciendo una revisión de lo planificado un programador ve una zona oscura le será más fácil exponerla detenidamente al líder técnico (o al compañero que participe en la estimación) que al líder de proyecto. Y es el líder técnico, que tiene más aceitada la "práctica de la reunión" el que está en mejores condiciones de traducirlo en un número para el líder, que usualmente no tiene interés en los detalles.

Otro de los puntos debatidos es la participación de los juniors o los expertos. Bueno, aquí está el tema de cómo definimos "junior". Un junior es por definición alguien que, más allá de su nivel de programación, no tiene experiencia. Mal puede estimar si no sabe más o menos qué es lo que va a hacer (y esto implica 80% experiencia y 20% corazonada). Además el nivel de abstracción requerido para estimar supera en mucho el que puede alcanzar un junior (si no es así simplemente no es un junior). Por supuesto que si un punto de la estimación no es más que un agregado de tareas uniformes que el junior ha repetido varias veces se le puede preguntar. Pero es diferente "¿Cuánto tardás en hacer un ABM estándar?" y luego multiplicar por 10 pantallas que más o menos creemos que van a ser, más un 30% por las dudas que preguntar "¿Cuánto tardás en hacer las pantallas de parametrización del módulo de tesorería?".

Es decir, lo que define a una persona como "experto" es que cuando sabe dice y cuando no sabe, sabe a quién preguntar. Si tenemos uno o varios expertos estimando tendremos también estimando a todos los juniors necesarios sin necesidad de alquilar un teatro para la reunión.

Para terminar... una mea culpa sobre las estimaciones "siempre optimistas" de los programadores... ¡es así, absolutamente! Pero no lo hago a propósito, lo juro.

Y una última nota sobre teoría. La única que me ha llamado la atención desde siempre, por lo coherente del planteo, es la de XP. Primero se determina a quién se le asigna la tarea, luego se pide la estimación (si es una tarea amplia tal vez sea necesario dividirla: en XP se mezcla el diseño con la estimación y esto con la codificación, y la codificación con la prueba y todo con todo, es fabuloso). ¿Qué importa si es un junior, un experto o un monito con navaja? Si parece mucho, se puede preguntar a otro cuánto tardaría él y en todo caso reasignar. Luego se proporciona feedback individual para que cada uno vaya ajustando sus propias estimaciones futuras (era así, ¿no? En todo caso es una buena idea).

Me estoy alejando de la seguridad de las costas que conozco de memoria para adentrarme en un océano desconocido. Sean los expertos indulgentes y didácticos en los comentarios, más que hirientes y sarcásticos como son de costumbre.

jueves, 14 de agosto de 2008

Más bromitas de o sobre Google.

Google minus Google nos permite excluir de los resultados de cualquier búsqueda los sitios de Google (algo que de todas maneras es posible hacer desde el mismo Google, pero bueno...), ideal para paranoicos acerca de la neutralidad de Google respecto de sus propias páginas.

Spam Google es una parodia que nos permite hacer una búsqueda en spam y basura en general.

Y haciendo click distraídamente por ahí encontré esta joyita (miren el dominio): una página en donde los técnicos del rey de la web revelan hasta el más íntimo detalle de su tecnología.

Vía Google Blogoscoped + un poco de suerte.

P.D.: En ésta entrada había encontrado Google Leet.

miércoles, 13 de agosto de 2008

¿De dónde sale ese olor?

En este preciso momento le estamos poniendo el moño a una versión de nuestra aplicación principal con vistas a una certificación bastante exigente, que incluye auditoría del código. Hay que imaginarse la situación del negocio: una vez certificada, cada corrección en la versión insumirá los $$$ correspondientes a las horas de laboratorio necesarias para aprobarla de forma que no se pierda el aval... y no regalan la hora, precisamente.

Cuestión que mi vida laboral en estos días ha sido un constante ping-pong entre un par de cuestiones amplias (de esas que llevan al menos unos días) y un millón de micro-incidentes que se van llevando 10 minutos, 15 minutos, 1 hora... más el tiempo necesario para cambiar de tarea.

Lo extraño es... soy más productivo así. Muchas veces, cuando me enfrento a tareas de largo tiro quedo "colgado" en la búsqueda de alguna idea que resuelva una cuestión que me impide seguir. Al tener un bonito stock de tareas de menor alcance (y también de menor exigencia de concentración), logro ese estado que describía en "Codificando... divagando... es lo mismo", al tiempo que combato la inevitable ansiedad que se produce al no estar codificando (por más experiencia que uno tenga, en algún punto del cerebro sigue encerrado ese tumor que dice "si no estás tecleando no estás trabajando").

No hay con qué darle. Por más tonto que parezca una buena cantidad de cuestiones menores (pero necesarias) resueltas en medio día levantan el ánimo y nos preparan para la hora de airear ese muerto maloliente que se está pudriendo debajo de la alfombra.

Y así tangencialmente, llego al centro de la cuestión, ponerle el moño a la aplicación. Como decía, es importante... un segundo, ¿de dónde sale ese olor?

  • Mmmm... necesito arreglar el incidente ése del ítem de menú que pertenece a más de un módulo... ¿Cómo definimos los menúes? Ah, si... para cada módulo varios menúes... psssss, qué olor.
  • Ah, en los ABM genéricos hay que desactivar las funcionalidades no permitidas de acuerdo a determinado estado del sistema. A ver... ah, es un componente independiente que actualiza directamente la base de datos... ¡cuántos gusanos!
  • Todo cumple con las especificaciones. Para borrar un cuestionario tengo que borrar a mano todas las preguntas asociadas, si no es peligroso. Pueden haber cientos de preguntas asociadas a un formulario... a ver... selecciono (sólo puedo una), click, detalle, eliminar, aceptar... selecciono otra, click, detalle, eliminar, aceptar... ¿levanto la perdiz o traigo la pala?
  • Bien, ahora sólo tengo que reutilizar esta clase, que por suerte está bien encapsula... ¿¡qué es este agujero!?
  • ¿Alguien sabe para qué sirve el método "object FactoryBackdoor(string className)"? (Respuesta: silencio)

Se entendió el punto. Toda aplicación tiene un cuartito con olor extraño y muchas moscas, (si no pregúntenle a Microsoft).

¿Cómo se define un muerto? Arriesgo una teoría:

  • Al menos uno del equipo sabe que está ahí.
  • La funcionalidad no es central.
  • El problema crece (se pudre) lenta pero ininterrumpidamente.
  • Se encuentra en un área del código que cae bajo la responsabilidad de más de una persona... o ninguna.
  • Pero por más encerrado que esté "en algo" (el olor) afecta al resto de la aplicación.
  • La corrección puede ser obvia pero muy trabajosa o peligrosa de implementar.

¿Y cuáles son los síntomas?

  • Algo se hace cada vez más grande, o algo se hace cada vez más lento.
  • En la reunión de avance tal tema se da como "implementado". Alguien está mirando al suelo. No hay comentarios.
  • Ciertas conversaciones se interrumpen o cambian rápidamente al aproximarse un analista o el líder de proyecto.
  • Alguien se queda sistemáticamente un rato más, sin que nadie se lo pida (probablemente esté moviendo el cadáver).
  • Surgen ideas locas para problemas aparentemente simples. Todos los programadores buscan la forma de no tocar "tal cosa".
  • Un incidente rebota como pelota de ping pong (a mí me rebota y a vos te explota).
  • Che, ¿cómo puedo hacer "tal cosa"? Cric-cric (grillos, todos muy concentrados en su trabajo).
  • Todos estamos tranquilos, pero alguien está muy nervioso.
  • Para alguna tarea sencilla alguien presupuesta un número desproporcionado de horas (o sabe lo que se va a encontrar, o piensa quemar el cadáver ocultándose en esas horas).
  • Intercambio de miradas cómplices, conversaciones en voz baja ("sé lo que hiciste la semana pasada").

¿Mas definiciones / ejemplos? Manden a los comentarios.

martes, 12 de agosto de 2008

Liberados los resultados de los desafíos.

Pueden consultar los comentarios de las entradas Desafío I y Desafío II para ver las respuestas (las que dejaron están bien).

Por problemas técnicos ajenos a mi persona ha sido suspendido el sorteo de la Nintendo Wii. Procederemos a sortear el premio alternativo, un huevo Kinder (en breve).

lunes, 11 de agosto de 2008

Hablando de programadores y líderes de proyecto...

Casualmente a desCerebrado (que algún día dará la cara o el nombre) se le dio por compartir esta entrada de Dirección de Proyectos en su reader, un chiste muy conocido que viene a cuento de "programadores vs. líderes de proyecto", y que tiene bastante que ver con lo que escribía en Comunica... ¿QUÉ? que posteaba justo hoy.

Didáctica orientada a objetos

Muy buena esta entrada del Blog de Alejo explicando didácticamente interfaces, capas de abstracción, encapsulamiento y otras yerbas... más o menos. Hay que leerlo para entenderlo.

Comunica... ¿QUÉ?

En varios posts (por ejemplo aquí y tangencialmente en muchos otros) hablé sobre la importancia de la comunicación en el equipo de desarrollo. De hecho, el trabajo en equipo es básicamente comunicación, y realmente poco más que eso.

El desarrollo de un sistema de software es muy sensible a los problemas de comunicación, a los malentendidos y confusiones en todo nivel: desde los requerimientos hasta el mantenimiento. Tal vez esta sensibilidad tenga que ver con que es la traducción de un proceso de negocio a varios lenguajes, desde los menos estructurados (relación con el cliente, análisis funcional, gestión del proyecto) hasta los más estructurados (lenguajes de programación, de consulta a la base de datos, de diseño de interfaz con el usuario).

Usualmente, para cada uno de esos lenguajes tenemos uno o varios profesionales en el equipo, y de alguna manera tienen que encontrar una base para entenderse. Pensemos por un segundo en qué diferente es el sistema visto desde el usuario, desde el líder de proyecto, el experto en base de datos, los programadores, los diseñadores, y nos parecerá casi un milagro que todas esas miradas logren coordinarse de alguna manera (cuando lo hacen).

En resumen, ya bastante difícil es la coordinación entre profesionales de una misma área (dentro del equipo de programadores, digamos), y se complica muchísimo más entre profesionales de distintas áreas.

Entonces, veamos el mismo problema desde dos puntos de vista diferentes. Es intersante ver que hay que pensar un rato para darse cuenta de que es el mismo problema.

Tomemos entonces "El éxito depende de tres cosas: comunicación, comunicación, comunicación" de Mejores Proyectos (un blog justamente orientado a líderes de proyecto).

Y por otro un aporte de Cerebrado, que creo que resume bastante bien cómo son caracterizados -a veces- esos "otros niveles" de un equipo de desarrollo.

ACTO I.

  • Líder (L): El reporte tiene que tener mas o menos éstos campos.
  • Programador (P): ¿Tiene o no tiene que tener el campo “X”?
  • L: Y... si hay lugar ponélo.

ACTO II. Dos meses después.

  • L: ¿Gente, por qué no está el campo “X” en el reporte?
  • B: porque no había espacio para ponerlo.
  • L: Pero... se suponía que tenía que estar.
  • B: ¿En qué charco está escrito que tenía que estar?

... continúan líder y programador en un sinfín de si-no.

ACTO III.

  • L: Listo, en ésta semana terminamos el módulo prometido.
  • Jefe máximo que paga los sueldos de todos (DIOS): la semana pasada me dijiste lo mismo
  • L: (Y la semana que viene le diré lo mismo, me parece) Sí, pero ésta vez ya está terminado.
  • DIOS: (Ya no te creo nada.) Bueno. ¿Le comunico al cliente que estamos instalando el viernes?
  • L: (El viernes me quiero ir temprano...) Mejor el lunes, por cualquier cosa.

ACTO IV. Ese viernes a las 18.00.

  • L: Muchachos, el lunes instalamos.
  • P: ¿Cómo? ¿Qué? ¿Cuándo? ¿Por qué? ¿Quién?
  • L: Sí, el jefe máximo dio directivas claras, pero no se preocupen, en mi planilla figura que estamos en término.
  • P: ¿Y cuando vimos nosotros esa planilla?
  • L: Ni hace falta que la vean, para eso estoy yo.
  • P: (¿Para qué era exactamente que estabas vos?)...

P llama a A (amigo) y le pregunta si el lugar donde labura está bueno. Como A es nuevo en ese trabajo le dice que sí. B manda el CV.

(TELÓN)

Mientras acomodaba todo esto pensaba "los programadores deberíamos leer más blogs de líderes de proyectos, analistas y emprendedores que de otros programadores", para acortar la brecha, para entender un poco más la mirada del otro lado (en la que somos los programadores los que quedamos siempre mal parados).

¿Alguien conoce?

domingo, 10 de agosto de 2008

XML * Inconciencia

Quería destacar de la lista de "Lo que leo" este post en el blog de Lucas Ontivero con una pequeña pero detallada lista de delirios y cosas raras que se pueden hacer con XML.

Me llama mucho la creatividad con la que algunas personas reinventan la rueda (dejándola cuadrada).

Un cambio de cara...

Habrán notado que... ¡prendí la luz! Estaba un poco cansado del fondo negro y letras blancas, me pareció que complicaban un poco la lectura. Así que empecé a jugar con la paleta y las fuentes. ¿Qué les parece?

¿Qué lenguaje de programación sos?

Otro cuestionario gracioso para atraer visitantes a una página web y de paso robar un par de links, esta vez para saber qué lenguaje de programación es más parecido a uno. Como verán me tocó perl (del cual creo que alguna vez en mi vida he visto dos o tres líneas de código).

You are Perl. People have a hard time understanding you, but you are always able to help them with almost all of their problems.
Which Programming Language are You?

Via Developing my life (que también es pearl).

sábado, 9 de agosto de 2008

COBOL sobre ruedas...

¿Quién dice que no se le puede enseñar trucos nuevos a un perro viejo?

En Pensamientos ágiles Martín descubre una nueva herramienta para el desarrollo web. Ideal para la web 0.2 2.0.

Refranero Geek

Refranero Geek en SpiderPig.es para toda ocasión.

Algunas de las que me gustaron:

- Historial ayer borrado, anteayer hubo pecado.

- A programa pirateado no se le miran las fuentes.

- Al idiota, bloc de notas.

...(y siguen)...

Vía Microsiervos.

viernes, 8 de agosto de 2008

El software y las catedrales.

El software y las catedrales se parecen mucho. Primero lo construimos, después rezamos.

-- Anónimo

Visto en Mundo geek (vía Cerebrado).

Escritura leet

Una de tantas bromitas de google escondidas por ahí... no la conocía.

Visto al pasar mientras leía este post de Emezeta Blog.

jueves, 7 de agosto de 2008

Desafío III

Muy fácil, casi ofensivo:

ONLY DEAD PEOPLE AND YOU CAN READ HEXA. DO YOU KNOW HOW MANY PEOPLE CAN READ HEXA?

La respuesta, aparte de obvia, está donde están todas las respuestas (¿hasta tengo que poner un link?).

Comparativa de salarios entre desarrolladores .Net y Java

Muy casualmente encontré publicado el dato en esta entrada del blog Mi carrera laboral en Informática y Tecnología. Si no he entendido mal este blog está mantenido por la misma gente del popular UniversoBit y los datos están extraídos de su propia base.

Más allá de eso vengo siguiendo el blog desde hace un par de semanas y es altamente recomendable para mantenerse al día respecto del mercado laboral y aledaños.

Resumen: que los programadores senior en Java están ganando entre un 10% y un 20% (cuentas a ojo, yo chequearía) por arriba. Para piratas de la informática puede ser una diferencia significativa, pero personalmente no me mueve a acción... no voy a empezar a aprender Java por estas razones, quiero decir.

miércoles, 6 de agosto de 2008

Implementando y manteniendo soluciones

Por soluciones entiendo aquello a lo que me refería en este post de hace unos días. Transcribo aquí lo mínimo para que no me tomen por las ramas, pero les recomiendo leerlo antes de seguir.

[...] puede pensarse en un parche y una solución para cada problema [...] El parche es la actividad que resuelve la situación puntual, mientras que la solución es un cambio en la metodología de trabajo o en el circuito administrativo dentro del equipo que torna imposible la situación que originó el error. [...]

Me quedé pensando en eso, llegando a relacionarlo con este otro, en el que divagaba sobre "El soporte del conocimiento". Hablaba sobre organizaciones en las que el conocimiento era soportado por los procesos y organizaciones en las que era soportado por las personas:

Si combinamos la "orientación a resultados" por parte de los jefes con la "obligación de acudir todos los días" por parte de los trabajadores, tenemos una organización en la cual el conocimiento está basado en el proceso. Lo asocié rápidamente con algunas las grandes consultoras de software, en las que los procesos están fuertemente establecidos y el trabajo es realizado por una pirámide de programadores [...]
En el otro extremo, si juntamos "orientación a las personas" por parte de los jefes y "realización personal" por parte de los trabajadores, podríamos suponer que el conocimiento está asentado en las personas. La imagen es la de un pequeño equipo de trabajo en el que las soluciones son discutidas entre iguales [...]

Juntando:

Los parches **provienen** del conocimiento almacenado en la organización, ¿de dónde si no? (acepto sugerencias). Si este conocimiento está soportado por procesos puede implicar, por ejemplo, la búsqueda de una serie de acciones a seguir en una "Knowledge Base" corporativa o el ingreso de un ticket a un sistema de incidencias. Si está soportado en las personas sería la típica situación en la que ante un problema alguien nos dice "preguntále a Fulano que es el que la tiene clara con eso".

En cambio las soluciones **aportan** al conocimiento en la organización. Nuevamente tenemos los dos extremos: este aporte puede estar materializado en un nuevo circuito administrativo comunicado formalmente mediante un memo o establecido en un sistema (conocimiento soportado en procesos), o en la mejor coordinación que surge en el equipo, mejores prácticas que se van comunicando, imitando y fortaleciendo entre y por sus integrantes (conocimiento soportado por las personas).

¿Qué pasa con esas soluciones a lo largo del tiempo? Pienso sobre todo en una pyme, en donde el conocimiento está esencialmente soportado por las personas.

Luego de incorporarme al equipo que ahora integro se sucedieron cambios de personal más o menos constantemente hasta ahora. Luego de casi dos años y medio sólo quedan dos personas del equipo original. Se fueron 5 y entraron 6 (algunos de los que entraron se fueron, se entiende) de un equipo que quedó más o menos formalmente establecido en 6 personas. Por suerte todos los que se han alejado lo han hecho en buenos términos y en forma más o menos espaciada en el tiempo (sólo por suerte). Conociendo por referencia casos de estampidas o reducciones masivas tengo que reconocer que todo se ha ido dado de una manera bastante tranquila, con apenas uno que otro sobresalto puntual.

Volvamos a la pregunta, ¿qué ha sido de aquel cúmulo de soluciones, de prácticas, de procedimientos, de relaciones de comunicación? Ha volado por los aires, por supuesto, y poco queda de ello.

Por un lado esta rotación, lenta pero continua, nos ha puesto en una senda de "formalización informal" (léase "paperless") creciente a tono con el perfil de los que fuimos entrando (se imaginarán sólo por el contenido de este blog cómo viene la mano por casa... y encima no soy el único).

No puedo decir que no hemos mejorado... pero esto es decir nada, ya que el conocimiento está basado en las personas, por lo que se produce una necesaria adaptación entre el equipo y cada uno. El que no se adapta se aleja o fuerza una adaptación o alejamiento por parte de los demás (dependerá de la relación de poder)... y los que queden siempre sentirán que fue para mejor, o por lo menos soportarán estoicos.

No se queden con la idea de que "para cada parche encontramos una solución" ni con que "cada solución fue consensuada e implementada exitosamente"... ni mucho menos. Para lograr algunos éxitos hay que pasar por un sinfín de pruebas, correcciones, errores, fracasos y vueltas atrás.

Pero lo interesante entonces es ver cómo se fueron dando los cambios que finalmente quedaron establecidos exitosamente, qué los diferenció del resto.

  • Fueron cambios pequeños, los intentos de "ponerse de acuerdo para ordenar todo el circuito" no funcionaron, incluso cuando estábamos todos de acuerdo.
  • Respondían a algún problema específico que se había repetido un par de veces. Si el problema no se repite tal vez no sea necesaria ninguna "solución". Por otro lado fue bueno "parchear la cosa" un par de veces para tener en claro de qué se trataba. Usualmente el origen del problema no está donde se presenta.
  • Propuestos e impulsados por pocos y llevados a consideración del resto. Ojo, no simplemente comunicados y mucho menos impuestos. Es mejor que una o dos personas presenten una propuesta -que puede "rebotar" un par de veces hasta llegar a una versión aceptada- que una eterna mesa redonda.
  • ...y muchas veces la comunicación fue simplemente "a ver, hagamos esto"... y es obvio cuando no funciona.
  • Siempre participaron los afectados. Una mirada de afuera está bien, pero tiene que ser solamente eso, una mirada de afuera.
  • Ninguna fue una solución óptima ni definitiva, sino simplemente un paso. Creo que la búsqueda de la perfección paraliza.

Probablemente me esté olvidando de algo (o pifiando en algo, veremos), espero no demasiado central. Quiero recalcar, sobre todo por esta última parte, que es mi experiencia, tal como yo la veo, y una generalización más bien en abstracto sobre eso. Es decir, en resumen, que como todas las cosas está puesta a prueba.