Flujo de lava.
El flujo de lava es un antipatrón en el que código oscuro y a medio terminar se solidifica en producción porque nadie lo entiende lo bastante para quitarlo.
En la jerga de la programación informática, el flujo de lava es un antipatrón que se produce cuando código fuente escrito en condiciones subóptimas se despliega en un entorno de producción y posteriormente se amplía mientras todavía está en estado de desarrollo. El término deriva de la aparición natural de la lava que, una vez enfriada, se solidifica en roca difícil de eliminar. De forma análoga, ese código se vuelve difícil de refactorizar o reemplazar debido a las dependencias que surgen con el tiempo, lo que obliga a mantener la compatibilidad hacia atrás con el diseño original e incompleto.
Causas
El flujo de lava puede producirse por diversas razones dentro de un proceso de desarrollo de software:
- La presión por cumplir plazos que hace que las soluciones temporales se vuelvan permanentes
- Documentación inadecuada que impide comprender el propósito del código
- Falta de pruebas automatizadas que hace que refactorizar sea arriesgado
- Cambios frecuentes en el equipo de desarrollo que provocan pérdida de conocimiento
Consecuencias
El código sin refinar que pasa a formar parte de la infraestructura del software aumenta la complejidad del sistema, y la base de código se vuelve cada vez más difícil de entender y mantener. Esto conduce a:
- La necesidad de compatibilidad hacia atrás, que puede ahogar la innovación e impedir la adopción de soluciones más nuevas y eficientes
- El aumento de la deuda técnica que se acumula con el tiempo, lo que da lugar a mayores costes de cambio y mantenimiento
- Obstáculos para refactorizar o mejorar el sistema por miedo a romper componentes dependientes
Impacto en los equipos
Los equipos de desarrollo suelen experimentar el impacto del flujo de lava cuando sus miembros entran y salen:
- Pérdida de conocimiento sobre aspectos del código del sistema cuando los desarrolladores originales se marchan
- Reticencia de los nuevos desarrolladores a refactorizar código que no les resulta familiar, lo que conduce a mayor complejidad a medida que añaden en lugar de limpiar
Estrategias de mitigación
Varias prácticas pueden mitigar los efectos del antipatrón del flujo de lava:
- Promover buenas prácticas de documentación para una comprensión clara del código
- Fomentar revisiones de código periódicas para detectar pronto las prácticas subóptimas
- Priorizar la refactorización como parte integral del ciclo de vida del desarrollo
- Mantener un conjunto completo de pruebas automatizadas para reducir el riesgo en los cambios
Ejemplo
La rama heredada de abajo sobrevive a cada limpieza: no tiene pruebas, ni ticket, ni documentación, solo un comentario de advertencia, así que nadie sabe para qué sirve y nadie se atreve a borrarla.
class Pricing {
// nadie recuerda quién activa este flag; no borrar, algo podría romperse
private static final boolean LEGACY_MODE = Boolean.getBoolean("pricing.legacy");
double price(Order order) {
double total = order.total() * 1.1;
if (LEGACY_MODE && order.items() > 10) {
total = legacyAdjust(total); // ???
}
return total;
}
private double legacyAdjust(double total) {
return Math.floor(total * 0.97);
}
}
La salida consiste en registrar el comportamiento actual con pruebas de caracterización, confirmar que la rama no se usa y entonces eliminarla:
// 1. Las pruebas de caracterización fijan el comportamiento actual antes de tocar nada
@Test
void addsTenPercentMarkup() {
assertEquals(110.0, new Pricing().price(new Order(100.0, 1)), 1e-9);
}
// 2. Una búsqueda en el código y la configuración de producción muestran que nadie define pricing.legacy,
// así que se elimina la rama; las pruebas confirman que nada más ha cambiado
class Pricing {
double price(Order order) {
return order.total() * 1.1;
}
}
El código inalcanzable no es más que código muerto, y el control de versiones lo conserva de todos modos, así que no hay motivo para mantenerlo «por si acaso».
Adaptado del artículo de Wikipedia “Lava flow (programming)” (revisión 1309138267), disponible bajo la licencia CC BY-SA 4.0; el texto ha sido traducido y editado, y se han añadido ejemplos.