Archive

Posts Tagged ‘deuda técnica’

Deuda técnica–qué es y cómo se detecta?

Cuántos de vosotros habéis oído de productos que, a pesar de arrancar brillantemente, vieron su desarrollo retrasado o totalmente detenido por problemas que no hacían más que aumentar con el tiempo a cada nueva versión?

debt
Hace unos días me hicieron llegar un excelente artículo de Enrique Dans acerca de la deuda técnica y cómo dicha deuda provocó la caída de los sistemas de British Airways que muchos miles de pasajeros padecieron. Y aunque estoy de acuerdo con el artículo, me pareció que el autor cargaba excesivamente las tintas contra la parte final del proceso: el mantenimiento del sistema una vez puesto en marcha, prácticamente igualando la deuda técnica al tiempo que transcurre desde que un sistema arranca y no es mantenido apropiadamente en producción.

La deuda técnica se define como los recursos (tiempo y coste económico) necesarios para resolver problemas en sistemas tanto en su fase de desarrollo como una vez puestos en producción. Con el tiempo, si dichos defectos de diseño o mantenimiento no se solucionan, no hacen más que incrementar los recursos – de ahí el término “deuda” que, como los tipos de interés, no hace más que aumentar con el tiempo – necesarios para resolver el problema.

El artículo de Enrique Dans analiza la generación de deuda técnica incrementada por un negligente mantenimiento de un sistema que, por otro lado, no aparentaba problemas de diseño. En lugar de emplear recursos de la empresa de forma constante para mantener los sistemas, se empleó personal externo para ello. Dicho personal externo, a medida que es reemplazado por otro personal externo sin el entrenamiento pertinente, no hacía más que empeorar los procesos – hasta que alguien tumbó el sistema. Es lo que yo considero “deuda técnica de IT”. Pero el sistema podría haber sido perfectamente funcional.

Pero mi concepto de deuda técnica viene de mucho más atrás. La deuda técnica empieza el día que se empieza el desarrollo del sistema.

La historia va así: alguien tiene una idea, posiblemente una excelente idea para un nuevo producto, un proyecto que podría ser incluso revolucionario. Manos a la obra, empieza el desarrollo, inicialmente con unas expectativas concretas, un punto concreto al que llegar para el lanzamiento. Aparentemente todo va según lo planeado, el desarrollo avanza según lo previsto: salimos en fechas.

Poco a poco, el desarrollo se va ralentizando, pierde ese empuje inicial, empiezan a aparecer problemas a cada paso que bloquean todo el desarrollo hasta que se resuelven. Al principio las paradas son relativamente esporádicas y se resuelven rápidamente, pero según avanzan las semanas cada problema se vuelve más “raro”, más complejo, requiere de más recursos, y cuando se soluciona uno, aparece otro por otro sitio. Es el síntoma obvio de un problema de deuda técnica: cada nuevo problema es más caro de resolver que el anterior, porque los problemas iniciales de diseño no se resolvieron en su momento.

Si cuando apareció el tercer problema, se hubiese realizado un análisis de los tres como un conjunto (y no simplemente parchear cada uno de ellos individualmente que es, tristemente, lo que los estándares de la industria dictan hoy en día) y solucionar el defecto de diseño inicial que los provocó, no habrían aparecido los subsiguientes problemas (y el desarrollo sería más rápido desde ese momento, sin innumerables paradas). Sí, arreglar el error de diseño al aparecer el primer problema hubiese requerido una parada de desarrollo (y las subsecuentes modificaciones de los módulos afectados), pero en las fases iniciales el número de módulos suele ser reducido y el impacto, limitado.

Pero si el desarrollo prosigue y se sigue tratando cada problema como una entidad individual, y se siguen desarrollando módulos sobre una base defectuosa (la deuda aumenta), cuando alguien determine que el problema no es puntual sino congénito, el coste de repararlo será masivo: implicará tanto aplicar la solución al problema de diseño más el refactoring de ahora una inmensa cantidad de módulos hechos a medida de ese defecto de diseño.

Imaginemos un problema del diseño base que se puede resolver (incluyendo testing) en cuatro días. Para completar los datos, asumamos que nuestros programadores ganan 60 euros diarios. Subsanar el defecto de diseño inicial costaría unos irrisorios 240 euros (60 euros multiplicado por 4 días).  Imaginemos que durante la fase inicial (el “tercer” fallo del que hablábamos antes) nos ponemos en el peor de los casos y el cambio en la base implica “breaking changes” que lo hacen incompatible con las implementaciones de los módulos implicados (hasta ahora, tres). Adaptar o reescribir esos tres módulos (y sus dependencias) implica7 días por módulo:

(4 días x 1 módulo x 60€) +
(7 días x 3 módulos x 60€)
= 1500€

Obviamente, puede que no se pueda hacer ningún trabajo en los módulos afectados mientras se realiza la corrección de la base, así que el costo de un número de programadores potencialmente “esperando” también aumentaría el costo, pero ya tenemos una cifra, en euros, que es lo que nos interesa. De los 240 euros iniciales ya nos hemos puesto en 1500.

Supongamos que nuestro director opina que esos 1500 euros, más un número potencial de programadores parados no es justificable y exige continuar con el diseño actual (al famoso grito de “eso ya lo arreglamos en dos patás más adelante”). El defecto de diseño persiste, se siguen escribiendo módulos dependientes, los problemas y errores ya están ralentizando el desarrollo (seguid multiplicando euros por horas). Ya está costando dinero (30? 40? 50 mil euros?), y eso que ni siquiera estamos arreglando el problema de base, porque los módulos dependientes llevan cerca de un 30% de código necesario para soportar el defecto de diseño inicial: estamos pagando dinero por escribir código “tirita” o “parche” y ni siquiera estamos en producción. La cifra ya es monumental.

Cuando llega el problema número quince, con docenas de módulos y dependencias afectados y el proyecto costando un dineral (por horas perdidas en ir “parcheando” defectos), llega el momento de la verdad y alguien, más arriba del director, decide que es momento de parar y solucionar el problema… Veamos ahora a cuanto asciende… Supongamos ahora quince módulos directamente dependientes, también con 7 días de refactoring, pero ahora con cada módulo soportando a su vez otros cinco elementos (35 en total), con un promedio de 5 días de media: algunos módulos se pueden aprovechar, otros toca reescribirlos o requieren una reescritura considerable:

(4 días x 1 módulo x 60€) +
(7 días x 15 módulos x 60€) +
(5 días x 35 módulos x 60€)
= 17040€

De los 240 euros iniciales nos hemos puesto en 17000 sólo para resolver el problema y sin contar el precio del desarrollo ya realizado sobre la base defectuosa (esos 30, 40, 50 mil euros). Y a este nivel del problema, lo más probable es que los programadores sí estén parados durante la reestructuración. Cuánto hemos gastado por no solucionar el problema al principio? Reparar el problema congénito sigue constando 240 euros, pero su deuda técnica ha sido masiva, potencialmente letal para el proyecto o incluso la empresa.

Ahora, ese alguien por encima del director, tendrá que decidir, no ya si invertir 17000 euros en reparar algo que no debía existir en primer lugar, sino en admitir el gasto de los 30, 40 o 50 mil euros empleados sobre una base defectuosa y que, más que posiblemente, también requieran más inversión. Es cuando empiezan a rodar cabezas.

De repente, los 240, o incluso los 1500 euros, parecen un precio de risa…