Uno de mis experimentos favoritos sobre el comportamiento es aquel que se hace con unos monos y un manojo de plátanos. Cada vez que un mono se acerca al manojo para coger un plátano se propina una descarga eléctrica al resto del grupo. Con el paso del tiempo los monos aprenden y se dedican disuadir por la fuerza a cualquiér congénere que trate de acercarse a la fruta.
Hasta aquí todo es muy lógico, lo curioso sucede cuando se van reemplazando los monos previamente electrocutados por otros que nunca sufrieron dicho castigo. Estos monos continúan propinando palizas a quienes se acercan a los plátanos a pesar de que ellos mismos nunca sufrieron los efectos de las descargas eléctricas hasta con que, con el paso del tiempo, se pega a cualquier mono que trate de acercarse a los plátanos sin que ninguno de ellos sepa porqué lo hacen.
La vida está llena de comportamientos que fueron útiles en un pasado lejano pero que han dejado de serlo largo tiempo atrás.
Es muy común encontrarse con este tipo de cosas en cualquier equipo de desarrollo. Un nuevo programador que se integra a un equipo suele sufrir mucho este tipo de situaciones. Al tener una mirada fresca sobre el código (y también sobre sus nuevos compañeros de trabajo), percibe claramente este conjunto de prácticas (algunas graciosas otras no tanto) que tienen más que ver con la historia o la cultura creada en el equipo que con cuestiones técnicas o lógicas. Prácticas que en algún momento tuvieron sentido pero ya no, y que nadie se ha molestado en cuestionar. Pecando con un poco de soberbia, el nuevo a veces tiende a pensar que sus compañeros no piensan demasiado (¡error!).
Si en este punto esperan comentarios sarcásticos sobre ese tipo de cosas, esta vez los voy a desilusionar. Si bien es claro que estas actitudes tienen sus vicios, son la otra cara de la moneda de lo más básico del proceso de desarrollo de software.
Porque esta repetición "sin sentido aparente" es consecuencia inevitable (y deseable) de la división por capas, el encapsulamiento y la división de tareas. A ver, seamos claros. Si tengo que programar la funcionalidad X y se que tengo que utilizar "MiClase"... ¿miro el código de "MiClase" para entender exactamente cómo funciona o miro código con funcionalidad parecida a la que tengo que hacer y que también utiliza "MiClase" para entender cómo se usa? ¿Hay algo de malo en esto?
Tal vez a alguno se le cruce por la cabeza "copiar y pegar sin pensar". No, no estoy hablando de esa situación (que también existe, pero esto es otra cosa). El programador mira el código, lo interpreta, lo entiende y lo encuentra razonable sin entrar en detalles. Entonces toma la referencia que necesita y la adapta.
Como programadores, tomamos mucho de lo que vemos "como está", sin cuestionarlo demasiado. Y cuanto más éxito tenemos en este camino, más reforzada se ve esta conducta. Podemos hacerlo si el proyecto está bien estructurado y el código es parejo en cada capa, que es lo esperable. Si el proyecto es una sopa de algoritmos ni siquiera encontremos qué copiar.
¿No les parece que hay algo como que está mal? Sí, las palabras. Si en vez de empezar este artículo hablando de monos pegándose unos a otros hubiese comenzado con "la documentación de referencia más importante es el código" todo sonaría mucho más lindo. ¿Por qué decimos que "el código es la referencia más importante" y utilizamos esa frase para obligarnos a respetar los estándares y las buenas prácticas hasta en las funciones más triviales? Porque todo el código, TODO, es pasible de ser utilizado como referencia, nos guste o no, de manera controlada o no.
Si dejamos una lógica medio enrevesada dando vueltas por ahí, o algún código comando, pensando "bueh, pero esto está encapsulado acá, y es algo sin relevancia"... volvemos dentro de tres o cuatro meses y lo vemos esparcido como un virus por todo el sistema... como TODO el resto del código, por otro lado. Sólo que cuando ese código "esparcido" no tiene nada de malo, prácticamente no nos damos cuenta.
Pero sí hay algo que está mal: volvamos al "nuevo". El tipo va y pregunta "¿por qué esto está hecho así?" Y le contestan "porque se hace así, siempre lo hicimos así". Esas no son razones para dar a nadie.
La respuesta más correcta sería "no sé, siempre lo hacemos así, pero si querés ver bien fijáte en tal lado". Es decir: obviamente nadie tiene en la cabeza el por qué de todo, pero si es indispensable que la estructura del proyecto permita inferir dónde está el por qué de todo. Yo no sé "por qué", pero sí sé que hay un por qué, y dónde buscarlo, por las dudas.
Y hay que estar abierto al cambio, a la mejora. Sigamos la anécdota. El nuevo va, mira, entiende, y como lo ve razonable se olvida de todo, no hay nada del otro mundo allí. Eso se repite un par de veces (digamos de paso que éstas son las "conductas observables" por las cuales se transfiere la cultura) mientras va aprendiendo un poco cómo se hace todo. Hasta que en una de esas sí encuentra algo que no tiene sentido.
¿Qué hacemos? Bueno, espero que haya quedado claro que la frase "dejálo y hacélo como siempre, siempre lo hacemos así" no tiene sentido, mucho menos ahora.
La opción de máxima sería corregir y corregir todos los lugares en donde esa incoherencia se ha "copiado y pegado", que es el equivalente a erradicarlo. Pero la realidad es que a menos que el proyecto esté infectado con ese tipo de cosas por todos lados (en tal caso está desahuciado), es más probable que el tema sea más o menos benigno. En este caso, alcanzará con cambiarlo de aquí en más y tal vez, de a poco el código corregido se distribuya tanto como el otro lo hizo en su momento.
Voy a por mi plátano, hasta el próximo post.