5 reglas para no boicotear un proyecto de software a base de "buenas prácticas"
Asegúrate de que tu equipo no se convierte en un pollo sin cabeza
Lunes, 9 de la mañana. Tu escritorio huele a café. Das el primer sorbo y miras el calendario. Parece un tablero de ajedrez. La productividad está por los suelos, cada bug que se arregla genera 3 nuevos.Tu manager está obsesionado por implementar “buenas prácticas”, lo que sea que eso signifique. El junior quiere implementar TDD porque lo acaba de ver en un video de Fireship y el senior sólo quiere que le dejen programar en paz.
¡No pasa nada! ¡Tengo la solución! DevOps para todos!! 🎉
Defines un proceso infalible donde hay que hacer una pull request, que se rechaza automáticamente si el linter o el formatter no acepta el estilo, que tiene que incluir tests y actualizaciones del changelog y cada línea de código tiene que ser un verso endecasílabo.
Es broma. Este cambio jamás va a salir bien.
El problema es que, por muy perfecto que sea este nuevo sistema, el equipo no sabe usarlo. No sabe cómo configurar cada herramienta, ni por qué hace falta. Sólo ve que cada vez que termina su trabajo, no puede incorporarlo a la base principal del código cada vez por un error distinto.
Peor aún, el fracaso minará la confianza de todos en un futuro mejor, y cualquiera que ahora proponga un cambio a mejor sólo consigue provocar en el resto flashbacks de Vietnam.
Implementar buenas prácticas es como hacer mayonesa
Formatter, linter, actions, tests, PRs, SOLID, DRY, KISS, AC/DC, Metallica…Todo a la vez. ¿Qué puede salir mal?
Si quieres arreglar las cosas necesitas un proceso de cambio que te garantice que:
- No se aplican de una vez más cambios de los que se pueden absorber.
- Todo el mundo entiende para qué sirve cada cambio que se adopte.
- Nadie se queda con fuertes opiniones en contra de ningúna decisión.
Para resolver este problema que durante años me he encontrado en muchos equipos utilizo lo que llamo La Constitución.
La Constitución
Cuando estaba en el instituto, un día nos vino a dar una charla un catedrático de derecho constitucional. Empezó diciendo algo que me extrañó bastante: “la Constitución es la única ley que no resuelve ningún problema”. 🤔
En realidad sí que resuelve un problema: poner a todo el mundo de acuerdo sobre qué consideramos que debería estar o mal hacer. Bajo estos cimientos, es mucho más fácil crear leyes que con un criterio arbitrario para cada situación.
La Constitución de un equipo de desarrollo es exactamente como la de un país: es la única ley que no resuelve ningún problema concreto pero establece un acuerdo común sobre con qué mentalidad se debe evaluar qué prácticas consideramos “buenas”.
Esta Constitución ahorra tiempo y disgustos: si no se está de acuerdo en algo, vamos a la Constitución y actuamos de la manera más fiel a esta. Al igual que en democracia, cuando alguien no esté de acuerdo contigo siempre podrás decirle: “¡ah! Pues cuando acordamos la Constitución dijiste esto”, y así ganar todas las discusiones.
¿Cuáles son los principios de la Constitución?
Cada equipo debe acordar en común estos principios, es lo que le da legitimidad. Como comienzo, puedes utilizar los míos.
1. La energía intelectual es limitada.
"La técnica es el esfuerzo para ahorrar esfuerzo."
- Ortega y Gasset
Es evidente que un trabajador de una obra se cansará mucho antes si transporta sacos de cemento a la espalda. Sería absurdo no utilizar al menos una carretilla. ¿Por qué en el software no hacemos lo mismo?
Hay gente que parece que cuanto más difícil hacen el trabajo más listos son.
A lo largo del día hay un límite de horas que podemos dedicar a crear software, incluso cuando entramos en un estado de casi adicción resolviendo algún problema. Llega un punto en el que es imposible concentrarse más.
Si queremos aprovechar al máximo la energía intelectual diaria, necesitamos hacer el menor trabajo posible.
Empleemos carretillas.
Algunos ejemplos:
- Utilizar un formatter (Prettier, Black, Ruff format…) en lugar de mantener el estilo a mano.
- Utilizar un linter que detecte potenciales errores y homogeinice el código sin tener que pensar.
- Utilizar herramientas basadas en IA. Hay gente que lo ve como un deshonor o algo así decir que las usa. No entiendo.
- Comitear con frecuencia en lugar de recordar cambios o copiar archivos por si hay que volver atrás.
- Aprender a utilizar tipado en lugar de memorizar qué tipo era cada cosa, usar assertions o simplemente confiar en yo no me voy a equivocar nunca.
- Crear tests automáticos básicos en lugar de realizar siempre las mismas pruebas en consola.
- Aprender atajos de teclado para las 4 tareas que se realicen constantemente en lugar de andar leyendo submenús haciendo decenas de clicks una y otra vez.
2. Toda solución necesita un problema.
Es obvio que todo problema necesita una solución, pero se nos olvida que una solución también necesita un problema. Adoptamos nuevos procesos sin pensar si de verdad los necesitamos.
- No se añade ninguna herramienta extra si no es para solucionar un problema.
- No se impone ninguna nueva regla si no es para solucionar un problema.
Eso debería evitar los clásicos “se tiene que hacer así porque es como se hace en [introduzca FAANG+]“. O mejor aún “así es como lo dictan las buenas prácticas”. 🤮
3. La estandarización es ortografía.
Durante un tiempo trabajé con un desarrollador muy crack pero que sólo había trabajado en solitario. Se preguntaba por qué debía respetar las guías de estilos del equipo, si todo se entiende igual.
A la hora de escribir en lenguaje humano respetar la ortografía no es necesario para entenderse. Sin embargo, tener una serie de reglas comunes para todos nos ahorra mucho esfuerzo.
- A quien escribe: no tiene que invertir energía constante en tomar la decisión de cómo escribir cada palabra
- A quien lee: necesita menos energía mental si todas las palabras aparecen escritas siempre de la misma manera, en lugar de tener múltiples grafías que significasen todas lo mismo.
El software es igual.
4. DX matters.
Un desarrollador infeliz es un desarrollador improductivo…y una próxima silla vacía. Las reglas deben, a medio-largo plazo, generar paz mental. Nunca infelicidad.
¿Qué hacer si quieres quemar a tu equipo de desarrollo?
- Oblígales a documentar todas y cada una de las líneas que escriben. Mejor aún, oblígales a mantener esos comentarios con cada cambio para que nunca dejen de ser verdad.
- Haz que tengan que escribir tests incluso para los prints.
- Impón un montón de herramientas lentas y pesadas contra su voluntad.
- Configura un montón de pre-commit hooks que les impida tener código sucio temporal en local para que no puedan hacer pruebas rápidas.
5. Los errores los cometen individuos. Las consecuencias las crean los sistemas.
- Ningún sistema debe depender de que nadie cometa fallos.
- Nadie debería trabajar con miedo a tocar nada, por si acaso se rompe algo.
Ejemplos:
- Alguien pushea a main por accidente y altera cambios en producción -> No existe una política de ramas que lo impida.
- Alguien elimina por error datos en la BBDD -> No había un backup automatizado, no había una política de roles y permisos eficiente.
Cómo garantizar esta regla: si algún nuevo desarrollador consigue romper algo, todo el equipo le invita a comer.
Sugerencias de extensión
A. La democracia no funciona.
A menudo un equipo puede sentirse tentado a tomar decisiones democráticamente. El problema es que el efecto Dunning-Kruger es demasiado potente en desarrolladores.
En lugar de eso, denomina a un dictador de confianza que decidirá qué se va a hacer. Deja que todo el mundo exponga su opinión y después deja que esa persona tome la decisión.
B. Si no se despliega no está terminado.
Desde escribir el código hasta que se despliegue y utilice, puede ocurrir todo tipo de errores. Para evitar el clásico “pues en mi ordenador funcionaba”, es conveniente desplegar los cambios, aunque sea en un entorno de desarrollo que al que el cliente final no tiene acceso.
Esta regla puede obviarse en función de la sencillez del proyecto y de los entornos involucrados.
C. No reinventamos la rueda
Aprender nuevas tecnologías existentes > crearlas desde 0.
Cuando el equipo es talentoso y entiende cómo funciona la tecnología que necesita, puede ser tentador crear todo de 0. De esta manera entenderemos perfectamente todo lo que está ocurriendo.
La alternativa sería aprender a utilizar una dependencia que ya tenga implementada la funcionalidad deseada. Construir es MUCHO más divertido que estudiar, por lo que la primera opción suena mucho más interesante, ¿no?
Sin embargo, con frecuencia se estimará de manera demasiado optimista el tiempo que conlleva hacer todo desde cero. Además, cada nuevo bug deberemos arreglarlo por nuestra cuenta, mientras que en el caso de una dependencia externa, esta responsabilidad recae en un tercero (o entre todos en el caso de open-source).
Repito: implementar buenas prácticas es como hacer mayonesa
No sólo porque si no se introducen los cambios gota a gota, todo se estropea. Sí. Pero también porque para que salga bien, primero se ha tenido que hacer mal.