viernes, 28 de febrero de 2014

Excusas para no documentar un código

En un proyecto de software tenemos dos tipos básicos de documentación. Por un lado está la documentación para el usuario final, para que aprenda a utilizarlo, como los manuales de ayuda o las referencias, mientras que por otro lado está la documentación sobre el desarrollo del mismo, como los diagramas de clases, casos de uso, o los comentarios en el código por ejemplo. Quiero hablar particularmente de los últimos, de los comentarios en el código (lo que se conoce como documentación interna) porque es algo que creo que a la mayoría no nos simpatiza mucho tener que hacer, pero que tampoco podemos delegar. El manual de usuario, por ejemplo, sí lo podría hacer por otra persona que no sea la que codificó el programa. Pero la documentación interna en general es responsabilidad directa del programador.

Como ya dije, es algo que consume tiempo y ganas, y por eso solemos inventar mil excusas para no hacerlo (o si es un proyecto individual, directamente no lo hacemos, sin tener que rendirle excusas a nadie). Pero a la larga, las consecuencias de una mala documentación terminan costando todavía más tiempo y paciencia (mucho más) de lo que habría costado hacerlo bien en su momento. Yo lo aprendí por las malas, mis códigos viejos son claras evidencias de ello, y por eso ahora vengo a refutar las excusas más comunes que nos ponemos para saltearnos ese trabajo.

He aquí entonces una lista de posibles excusas para no documentar un código y sus posibles respuestas:
  • "No tengo tiempo ni ganas": menos tiempo vas a tener para ponerte a analizar como funciona todo ese monstruo de clases y funciones mal programado cuando vuelvas después de dos semanas de vacaciones o de trabajar en otra cosa y ya no te acuerdes qué era cada variable, para qué servía cada función, o qué significaba ese décimo-tercer argumento void*. O peor aún, cuando tengas que corregir un bug, tal vez insignificante, pero no sepas predecir hasta dónde repercute el cambio que estás por hacer ni qué consecuencias más nefastas que evidentes podría tener ese pequeño aleteo (y esto pasa mucho).
  • "Nunca voy a volver a necesitar esa función": Suena trillado, pero nunca digas nunca. Los proyectos pueden crecer más de lo esperado, bifurcarse, especializarse, complicarse, interactuar con otros, o simplemente ocultar bugs por años hasta que un buen día al azar salen a vagar por la vida. Siempre puede haber alguna razón que te haga querer volver a ese código más adelante y que cuando lo hiciste no imaginabas. Si hay cero chances de que reutilices o retoques ese código, es probable que no sea un buen código, que tengas un problema de diseño un poco más arriba por falta de generalidad. Pero el solo hecho de pararte a pensar qué y cómo documentar puede disparar en tu cabeza las preguntas adecuadas para darte cuenta de ello.
  • "Es obvio lo que hace": Es obvio ahora, en este contexto, después de haber trabajado horas con esto y estar con la cabeza metida en el proyecto, teniendo presente qué hace y cómo trabaja esa función, teniendo fresco qué necesitabas. Pero esperá que pasen unas semanas sin tocarlo y vas a ver que no era tan obvio, que la función ahora es una mas de cientos que usaste, que tenés que repensar el por qué de cada una, que es complicado seguir el hilo del algoritmo si en cada paso hay que cambiar de contexto para analizar alguna función que se está llamando, etc. A veces el problema es algo indirecto, el nombre no siempre dice lo que hace aunque esté bien puesto. Digamos por ejemplo que llamas a stable_sort, está claro qué hace en general stable_sort y no hace falta documentar eso en la llamada, pero puede no estar nada claro porqué necesitás un stable_sort, y no un sort común, o un stable_partition en lugar de ordenar por completo, etc. Los porqués implícitos dejan de ser obvios rápidamente.
  • "Es código temporal, ni bien pueda lo rehago bien y ahí sí lo documento": si no lo rehacés literalmente enseguida, cuando tengas que rehacerlo ya no vas a tener tan claro qué era lo que hacía o, mucho peor, porqué querías rehacerlo en primera instancia. Ni hablar si te olvidas de que le faltaba algo más que documentación, que no terminaste porque total era provisorio, y lo seguiste usando como si estuviera listo. En programación tenemos que manejar varias capas de complejidad (distintos niveles de abstracción/detalle), y al programar vamos subiendo y bajando entre ellas. Y cuando nos salimos temporalmente de lo que estamos haciendo para ir a corregir/analizar algo a otro nivel, no sabemos cuanto vamos a tardar en volver. Es bueno aún para el código temporal documentar qué hace, qué debería hacer, cuales son los casos espinosos o los problemas de performance por los que hay que rehacerlo, etc. Además, es probable que cuando lo rehagamos la documentación de la nueva versión tome mucho de aquella documentación temporal inicial, así que de todas formas no es perder tiempo.
Estas son solo algunas excusas, pero que escucho (y uso) con demasiada frecuencia. Hay que reconocer que la documentación no es todo, siempre es importante además un código prolijo, bien indentado, con un estilo uniforme, nombres de clases/funciones/variables/archivos autoexplicativos y elegidos con un mismo criterio, cuanto más corto y modularizado mejor, etc. Documentar poco un poco de código es mejor que documentar mucho un montón de código. Siempre que podamos reutilizar funciones y clases de bibliotecas para que nuestras propias funciones y clases sean más cortas y acotadas mucho mejor por varias razones, pero de paso reducimos la documentación necesaria para que no nos de tanta fiaca y podamos centrarnos en la parte importante. Porque tampoco hay que abusar de los comentarios o se pierde el foco de lo que realmente importa. Un buen y constante estilo de codificación ya hace una mitad del trabajo evitando la necesidad de documentar cosas realmente triviales o que deberían ser en verdad obvias; los comentarios están para completar todo lo demás.

Un ejemplo en el cual el comentario explica algo para nada obvio
(tomado de http://xkcd.com/221/)

En conclusión, documentar no es un "gasto" de tiempo, sino una "inversión". Solo que muchas veces es una inversión a largo plazo, por eso no siempre se ve como tal. Y solo hablé de cómo lo beneficia a uno mismo en relación a su propio código. Ni hablar de lo que significa documentar cuando se trabaja en equipo, intercambiando código con otras personas, y modificando o corrigiendo diseños e implementaciones ajenas.

Como comentario final, quiero mencionar algo que me ayudó a mejorar mis hábitos y me obligó a documentar un poco más (además de la experiencia de encontrarme con códigos propios después de un tiempo y pensar que estaban escritos por alienígenas sin cerebro). Hablo del uso de herramientas como Doxygen, que se dedican a extraer los comentarios de los fuentes y generarnos automáticamente referencias para las interfaces de nuestras clases y funciones, con un lindo formato e hipervínculos, índices varios y facilidades de búsqueda, etc. En alguna próxima entrega de la serie "herramientas mágicas" pondré algunos ejemplos como para seguir en esta linea. Mientras tanto, no sean perezosos como quien escribe, y empiecen a poner más comentarios en sus códigos.

No hay comentarios:

Publicar un comentario