Entendiendo la Deuda técnica

lunes, 22 de septiembre de 2014

Más de una vez nos ha pasado de estar en la encrucijada de tener que decidir si resolvemos una funcionalidad de la forma más rápida pero no tan ordenada o elegante - aún sabiendo que en algún momento habrá que modificarlo , o hacerlo más ordenado y prolijo pero sabiendo que llevará más tiempo en terminarse.

Cualquiera de las dos opciones tiene sus consecuencias pero podríamos decir que en muchas oportunidades la urgencia del cliente tiene mucho peso y terminamos decidiendo por el camino más corto.

Ese tipo de soluciones - que trasladan al futuro cambios que pueden ser más costosos que haberlos implementado en el momento -  pueden considerarse deudas técnicas y las mismas pueden resultar en altas tasas de defectos, baja velocidad de respuesta, baja calidad del producto, baja productividad, problemas de mantenimiento, entre otros. Y no debemos olvidar los costos en el presupuesto.

Las deudas técnicas pueden estar relacionadas con distintos aspectos del desarrollo: algunas pueden ser debido al código (código repetido, complejo, difícil de entender y mantener, etc.), al entorno de desarrollo, la plataforma usada, el diseño, testing automatizado y demás.

Ward Cunningham utilizó una metáfora comparando este tipo de problemas del desarrollo de software con una deuda financiera. Es decir, queremos pagar la deuda con sus intereses en el futuro o pagamos el costo completo en el presente?

Esta metáfora también "justifica" que en determinadas circunstancias la elección de la solución rápida puede ser la adecuada cuando, por ejemplo, se quiere aprovechar una oportunidad de mercado, lo que en el desarrollo de software podríamos traducir como llegar a una fecha límite.

Creo que el mayor dilema en estos casos es saber cómo administrar las deudas técnicas y tratar de determinar a qué tipo de deuda nos estamos enfrentando para tener idea de la gravedad de la misma.

Algo que puede ser útil para esto es el Cuadrante de la deuda técnia creado por Martin Fowler.

Este cuadrante podría usarse para decir qué tipos de deudas son aceptables o no y usar esta información para establecer tácticas que nos permitan prevenir conductas o patrones inaceptables.

Fowler dice que, en realidad, la gran elección no es si tener o no deudas ténicas, sino que la decisión está en tomar Deudas Prudentes o Deudas Imprudentes. Además de determinar si son Deliberadas o Inadvertidas.

Una deuda Prudente y Deliberada se da cuando el equipo sabe que está incurriendo en esa deuda y supone una evaluación del costo futuro vs. el costo actual. Este tipo de deuda se considera "positiva" y su administración se hace más simple.

Las deudas Prudentes pero Inadvertidas suelen darse en casi todos los proyectos, dado que a medida que se va desarrollando los miembros del equipo van haciendo un aprendizaje que les permite darse cuenta que hay cosas que podrían haberse hecho mejor. Mucho más se da este fenómeno si el equipo cuenta con miembros menos experimentados. En estos casos lo importante es "pesar" si vale la pena corregir lo ya hecho o qué cosas puntuales sí deberían modificarse, según el impacto que puedan acarrear.
Para Fowler este tipo de deudas son inevitables y desde el inicio del proyecto todos deberían estar advertidos de su posible aparición.

Las deudas imprudentes suelen ser tomadas por equipos que desconocen las prácticas de diseño dado que no tienen la capacidad de evaluar cuál será el costo futuro.

Una deuda imprudente y advertida puede ser un caso muy peligroso. Se da cuando el equipo, aún teniendo conocimientos de buenas prácticas, decide que escribiendo un código más limpio no puede cumplir con los tiempos requeridos. Son muchos los factores que pueden llevar a tomar esta decisión:

      • mala gestión, 
      • presiones innecesarias, 
      • problemas en el equipo interno, etc..

Acumular este tipo de deudas implica que la calidad del producto va a ser muy baja.

Por otro lado, el creer que escribir un código desprolijo es más rápido que hacer un código limpio es un error.
La aplicación de las buenas prácticas tienden justamente a que el desarrollo sea, a la larga, más rápido y el código mucho más confiable.

Las deudas imprudentes no deberían ser, además, inadvertidas porque la acumulación de las mismas llevaría al fracaso del proyecto. En general este tipo de deudas salen a la luz por inexperiencia o falta de conocimientos del equipo o de los responsables.
Ocurre en general cuando los desarrolladores no tienen noción de las implicancias de cambiar una parte del código. Este tipo de deudas deben ser administradas con mucho cuidado.

Srinath Ramakrishnan en su artículo Managing Technical Debt sugiere la utilización de herramientas como pair programming, code reviews, integración continua, testing automatizado, etc.:

"La clave para administrar deudas técnicas es estar constantemente vigilante, evitar usar atajos en el código, usar diseños de aplicaciones lo más simple posible, hacer refactoring frecuente. "


Artículos de interés:

Managing Technical Debt
When code is considered Technical Debt
Technical Debt
Deuda Técnica
Uso de técnicas agile para pagar la deuda técnica
La mala calidad del software al final se paga