Estaba a punto de responder al comentario de Iboisset sobre Panqueque System II cuando me dí cuenta de que daba al menos para un pequeño post.
Aquellos que estamos ya un poco viejitos vivimos la revolución de las metodologías ágiles como un viento de aire fresco que barrió con viejos conceptos metodológicos que nos condenaban (a los programadores) a ocultar prácticas hoy habituales, pero que en ese momento se consideraban poco menos que meritorias de pena de muerte.
Es decir: nosotros ya programábamos de a pares, diseñábamos a medida que codificábamos y pensábamos en el cambio continuo, sobre todo en pequeños y medianos emprendimientos donde el peso del ciclo de vida no era tan asfixiante.
Y también, de vez en cuando... refactorizábamos.
Pero no como ahora, que utilizamos pruebas automáticas (o directamente programación guiada por pruebas), en donde (si tenemos suerte, pero en general es así) el manager del proyecto sabe que hay que probar la funcionalidad continuamente y entiende cuando le decimos que necesitamos recodificar o rediseñar cierta parte de la aplicación sin cambiar su funcionamiento, y nos permite asignar horas a esa tarea de forma abierta y planificada.
Si nos pedían una nueva funcionalidad o el arreglo de un error, éso era lo que iba a presupuestarse, implementarse y probarse. Y si el código estaba tan enrevesado que era imposible hacerlo en los tiempos requeridos (calculados muchas veces en base a los requerimientos sin tener en cuenta la calidad del código existente donde tenían que implementarse)... bueno, a eso se le llamaba "aumento de la curva de costo de mantenimiento", se suponía inherente al desarrollo de software y la solución propuesta era, simplemente, agua y ajo (aguantarse y ajoderse).
Eso en la superficie. Por debajo, como nosotros la sufríamos, había ocasiones en las que... ¡máh sí! ¡Yo lo doy vuelta como un guante! Agarrábamos, presupuestábamos un par de horas de más en algún requerimiento, tratábamos de que pase desapercibido, y hacíamos esa modificación transversal que tanto necesitábamos para odiar un poco menos nuestro trabajo de mantenimiento.
¿Pero quién nos probaba? Si modificábamos algo que impactaba en casi todo el sistema no podíamos decírselo a nadie... si surgía algún error en alguna pantalla que "nadie había modificado" había que disfrazarse de nadie para pasar desapercibido.
Aquí engancho el comentario de Iboisset:
"No obstante, en mi opinión, para esto también hace falta un perfil alto en el equipo, no todos los miembros del equipo "saben" hacer el código bien. Se me enfadarán pero es así."
En aquellos tiempos era imprescindible un perfil alto en el equipo, por las razones arriba mencionadas. Hoy, como bien dice Iboisset, también. Pero por suerte tenemos herramientas que permiten alcanzar ese alto nivel aprendiendo de la mejor manera posible: haciendo.
Con un buen conjunto de pruebas unitarias y un equipo de testing funcional despierto y consciente de que hubieron modificaciones transversales al sistema, el programador puede experimentar, intentar y equivocarse hasta lograrlo sin arriesgar su vida en el intento.
La diferencia de trabajar bajo una u otra metodología es brutal:
- La calidad de todo el código mejora con el tiempo.
- La calidad de nuestro trabajo mejora con el tiempo.
- Porque al intentar un refactory, y aunque no lo logre, el programador gana en conocimiento sobre todo el sistema, sin quedar estanco en las porciones que él conoce o que ha implementado.
- El mantenimiento se hace interesante, no una pesada carga. Una pequeña corrección puede llevarnos a descubrir un nuevo patrón y a implementarlo en el resto del sistema. Mantenimiento ya no significa necesariamente una interminable sucesión de pequeños parches.
Pero refactorizaciones... ésas eran las de antes. Sin red, como trabajan los programadores de verdad.