martes, 24 de febrero de 2009

Siguiendo el rastro del WTF.

perro Una tarea que se perfila como rutinaria puede transformarse inesperadamente en análisis forense funcional.

La asignación -más que rutinaria, aburrida-, era migrar un reporte del sistema viejo al nuevo. Usualmente se resuelve con un par de adaptaciones y listo, pero…

Mi primer descubrimiento en la tarea comenzó consistió en el procedimiento almacenado más enrevesado que vi en mi vida: una sola instrucción SELECT de más de 300 líneas, con tres niveles de subconsultas y un par de UNION’s en cada uno de ellos. Un bonito WTF.

Por supuesto que una maraña de código de ese calibre no es puntual ni tiene un sólo padre. Es el producto más paradigmático (entre muchos otros) de una larga cadena de producción de basura útil. Una cadena de errores que puede recorrerse hacia atrás desde la codificación hasta la gestión del proyecto.

La codificación, ilegible, traicionera y escurridiza, es el producto de “construir un rascacielos con ladrillos”. Es decir, se pretende resolver  todo el problema con una sola herramienta (¿qué necesidad había de hacer todo en una sola consulta?) en vez de separarlo en partes y aplicar a cada una la más adecuada.

No tiene sentido buscar un culpable, obviamente no lo hay. Si bien el código nació medio enrevesado fueron las sucesivas modificaciones las que lo volvieron caótico. Un buen ejemplo de la parábola de la rana hervida: pequeñas modificaciones, todas ellas muy inocentes tomadas en forma individual, generan un bonito quilombo desastre.

Lo que nos lleva a la metodología. Una refactorización a tiempo hubiese cortado este problema de raíz. Es claro, por la estructura de la consulta (bloques SELECT conectados por UNION’s que agregan casos no contemplados, subconsultas que vinieron a reemplazar referencias a tablas, cálculos repetidos que producen pequeños ajustes sobre el  resultado sin alterar la estructura, reutilización de campos para agregar datos “sin tocar nada”, etc.), que su creador sabía mucho más al final del proceso que al principio. La refactorización no sólo es imprescindible para mantener el código legible a través de las sucesivas modificaciones, es la actividad con la que se solidifica el aprendizaje, el momento en que lo aprendido se transforma en código. Aquel primer autor partió tiempo atrás y todo el conocimiento acumulado, por lo menos en lo relativo a esta experiencia en particular, se ha perdido irremediablemente (snif).

Esto es triste, sobre todo combinado con el hecho de que luego de un tiempo este código se ha convertido en la única documentación existente sobre la funcionalidad.

Lo que nos lleva al segundo error metodológico: ¿cómo transmitió el sector de análisis las especificaciones del reporte? No lo sabemos. El sólo hecho de que no lo sepamos hace de esa transmisión un acto fallido. ¿Fue verbalmente? ¿Se elaboró un documento? En todo caso, la falta de un soporte o repositorio confiable hizo humo (o leyenda) ese trabajo de análisis.

El que crea que el conocimiento puede preservarse “solo” en la cabeza de los integrantes del equipo puede acompañarme en la experiencia de consultar a las personas directa o indirectamente involucradas con una funcionalidad en particular. Lo que se obtiene son varios pedazos -ligeramente diferentes y que no encajan del todo- de la misma fotografía. Los detalles… “mirá el reporte en el sistema viejo”, con lo que volvemos a nuestro querido e ilegible procedimiento almacenado.

Entonces el problema es no de una o unas personas sino de todo el equipo. Nadie trabajó aislado. El analista hizo su trabajo, el programador hizo su trabajo. ¿Entonces? Lo que ha fallado es la interacción entreambos. La falta de visión a futuro (o la indiferencia con respecto a él), o un exceso de individualismo (“sólo hago mi trabajo”).

Los problemas de equipo son, por definición, de liderazgo. Cuando las partes no coordinan bien entre sí es necesaria la intervención de un elemento superior que modifique esa interacción: por caso, el líder. Por complicidad, desconocimiento o falta de soluciones (es irrelevante) eso no ha ocurrido.

Esta basura útil, este “cowboy code” incrustado en medio de un “pure chaos environment” funciona. Y bastante bien, por cierto. Entonces, en la mirada miope o distraída de líder, el equipo debe haber superado con creces el desafío, que quedó cerrado y archivado definitivamente.

El siguiente eslabón de la cadena es organizacional. La vara (ya sea para medir o aleccionar) más común en las organizaciones es el costo/beneficio. El costo de no haber documentado el análisis y refactorizado el código ha pasado desapercibido, lo que ha devenido en una medición inflada del resultado final, generando un pernicioso condicionamiento positivo respecto del apuro y la desprolijidad. Tal vez una medición más precisa del costo a futuro de esas desprolijidades hubiese motivado una corrección más temprana.

Esta última observación excede el ámbito de la gestión de un proyecto. Está más relacionada con la estructura de costo de la organización, del sistema que utilice para medirlo y de cómo se utilizan esas mediciones. El costo de este retrabajo, originado en aquél otro proyecto que salió “tan bien” y fue “tan rentable” pesará sobre este nuevo proyecto.

En fin, hemos comenzado hablando de procedimientos almacenados y prolijidad del código para terminar en cálculo y gestión de costos a nivel organizacional. Hemos recorrido, a través de un divertido ejemplo la cadena que une el error con la pérdida (en el mejor de los casos) o el fallo con la catástrofe (en el peor).

No hay comentarios.: