Sunday, September 06, 2015

Coste basal del software vs capacidad infinita


En mi opinión, el coste de desarrollo por cada grupo de funcionalidades se puede dividir de la siguiente forma:
  • Coste inicial de desarrollo
  • Coste de existencia (coste basal):
    • Coste de existencia / complejidad añadida
    • Coste de existencia para otras funcionalidades


Coste inicial de desarrollo

Este es el coste/gasto en el que incurre el equipo durante el desarrollo inicial de la funcionalidad. Incluye desde que el equipo comienza a trabajar en la funcionalidad o grupo de funcionalidades hasta que el cliente la tiene disponible y comienza a usarla. Por supuesto este proceso debería incluir múltiples puestas en producción para ir obteniendo feedback y realizando los ajustes necesarios...

A partir de este momento, comienzan a producirse de forma continua y hasta el final de la vida de la funcionalidad o del producto, un coste de existencia o coste basal.

Coste de existencia o Coste basal

Este coste, continuado en el tiempo y que solo termina con la retirada de la funcionalidad o el fin de la vida del producto, es el coste en el que incurre el equipo por la existencia de ese código y esa funcionalidad en el producto.
Es importante tener en cuenta que este coste no se refiere al coste de realizar modificaciones a la funcionalidad o corregir errores, se refiere al coste que conlleva simplemente que el código esté ahí...

¿Por qué se produce este coste?
  • El equipo tiene que conocer ese código (dónde está, qué dependencias tiene, con quien interactua, cómo está escrito...)
  • El conocimiento y técnicas del equipo están en continua evolución. Cuando el equipo mejora en alguno de estos aspectos tiene que decidir si actualiza el código de la funcionalidad, si lo hace es un coste, si no lo hace, también puesto que será diferente que el resto de código de que dispone.
  • Cuando aparezcan nuevas funcionalidades se debe ver dónde impactan y no es lo mismo tener que identificar esos impacto en una aplicación de un tamaño X que en una de un tamaño X más el tamaño de la funcionalidad.
  • Lo mismo pasa cuando entra un nuevo miembro del equipo y tiene que conocer la base de código que existe.
Y lo peor de todo es que este gastos es continuo hasta la "muerte" de la funcionalidad, es decir el fin de vida del producto, hasta que no la use ningún usuario o hasta el fin del mundo (lo que sea que ocurra antes).

Además, si se sobrepasa el punto de obsolescencia tecnológica (versión de lenguaje obsoleto, dependencias que desaparecen, etc) antes de la "muerte" de la funcionalidad el coste de mantenimiento se dispara y podemos entrar en una situación en que la capacidad del equipo quede ocupada al completo intentando mantener bajo control funcionalidades que ya han pasado el punto de obsolescencia tecnológica.

En mi experiencia, siempre me he encontrado que este coste se obvia y tanto los desarrolladores como los clientes y managers simulan que no existe, tomando decisiones (sin sentido) que no lo tienen en cuenta.

Capacidad no infinita

El problema es que la capacidad de un equipo de desarrollo no es infinita y aunque cambia (en positivo o negativo) con el tiempo debido a distintos factores (el conocimiento del negocio, de las técnicas...), existe una tendencia clara a que la capacidad usada en el coste basal de las funcionalidades ya hechas vaya mermando la capacidad disponible para nuevas funcionalidades.

Coste acumulado
Por tanto de forma general, independientemente de la calidad del software desarrollado, poco a poco la capacidad disponible de un equipo para nuevas funcionalidades disminuye con el tiempo.
Si el equipo desarrolla sin usar buenas prácticas y sin alta calidad, este colapso es prácticamente inmediato en el caso de tener muchos bugs o en unos pocos meses cuando aún no teniendo muchos bugs la calidad interna del software es baja.

Si el equipo es bastante bueno y se preocupa por la calidad esta tendencia será muchísimo menos pronunciada y se podría tener una capacidad "razonable" para nuevas funcionalidades durante años, pero por supuesto poco a poco iría disminuyendo y a la larga desaparecería.

A lo largo de los años las estrategias que he visto para lidiar con este problema son:
  • Ignorarlo y esperar al colapso.
  • Hacer crecer de forma constante tu equipo para mantener una capacidad para nuevas funcionalidades constante (este enfoque es el que parecen tener empresas de tecnología puntera que crecen en ingenieros de forma constante; google, amazon, netflix, spotify ...)
  • Crear equipos de mantenimiento a los que pasar el producto despues del desarrollo inicial (por supuesto esto es similar al punto anterior).
Claramente este problema sólo afecta a los departamentos de desarrollo interno o a los equipos de desarrollo dedicados a producto. Para el caso de consultoras o equipos que trabajan en proyectos este tipo de problema no les afecta puesto que pasado el desarrollo inicial se suele entregar el proyecto y el mantenimiento es problema del cliente.

La solución

Y ahora viene cuando planteo la solución que he encontrado....
Pues no, no tengo ni idea de cómo solventarlo, como mucho se retrasar las consecuencias del problema, minimizarlo, pero no solventarlo.



Me encantaría opiniones sobre como tratar a medio largo plazo este problema. Lo único que se me ocurre es el crecimiento continuo de equipo o tener una política de "end of life" de los productos muy agresiva.

Se aceptan sugerencias, experimentos, opiniones, cualquier comentario será bienvenido.

4 comments:

Jose Manuel Beas said...

Hola Eduardo,

Tu artículo me parece muy interesante y hace una reflexión económica de las que a mí me gustan. Si llevamos tu modelo a los extremos creo que nos aparecen un par de reflexiones interesantes.

1) Supongamos que fueramos capaces de arrancar un proyecto sin coste inicial. En ese caso tendríamos un producto donde todo es nueva funcionalidad y mantenimiento de las anteriores. Esto es parecido a cuando hacemos Agile y nuestro proceso de descubrimiento de nuevas funcionalidades (que forma parte del coste de desarrollo inicial de cada funcionalidad) es muy-muy liviano (sin impactar en la calidad del producto).

2) Supongamos que fueramos capaces de desarrollar un producto de manera que la tendencia de crecimiento exponencial de los costes de mantenimiento pudieran estar más "a raya". ¿Nos conformaríamos con un crecimiento lineal en vez de exponencial? Yo, personalmente, sí. ¿Qué habría que hacer para ello? A mí me suena que tiene que ver con la automatización de pruebas por un lado (que de paso sirven para documentar el funcinoamiento esperado del producto) y con las buenas prácticas de diseño (interno y externo) del sistema. El empleo de SOLID para el diseño interno, p.ej. o patrones de usabilidad para el diseño externo. De esta manera no sería necesario tener en la cabeza cómo funcionan todos los algoritmos de nuestro sistema sino sólo los que tienen que ver con la parte del sistema que está más sometida a cambios. Como sabes, los patrones, en general, ayudan a mantener a raya los costes de mantenimiento porque se pueden transformar unos en otros. De ahí que los ingenieros vayamos aplicando patrones a todo lo que se mueve. :D

Bueno, ahí van mis dos céntimos.

Eduardo Ferro Aldama said...

Muchas gracias por la opinión. Veo que coincidimos en la forma de mantener a raya el coste de mantenimiento del sistema.

Por otro lado, me ha gustado la opinión de que conseguir un crecimiento del coste lineal en vez de exponencial podría ser suficiente. Desde luego me quita un poco de ansiedad el saber que más gente entiende la complejidad de simplemente mantenerlo lineal.

Sería brutal encontrar la forma de mantenerlo en O(log n)
:)

Juan Carlos Quijano Abad said...

Si bien tienes toda la razón en lo que dices, me falta la parte de beneficio o ROI que genera este coste.

Sin ello no hay forma de saber si es coste o inversión, porque en algunos casos el ROI cubrirá este coste haciéndolo rentable y en otros será, efectivamente un coste en los resultados.

También habría que incluir en la formula el coste y ROI del cambio por caducidad, ya que puede ser que el coste sea tan alto o el ROI tan bajo, que el coste por mantenimiento realmente sea un beneficio.

Bonito articulo, gracias.

Eduardo Ferro Aldama said...

Gracias por el comentario Juan Carlos. Se me había pasado contestarte.

En nuestro caso, el software desarrollado es solo una parte de nuestros productos, por lo que es difícil calcular de forma directa ese roi. Vendemos sistemas de telecomunicaciones (productos) y no tiene sentido la venta del software de forma independiente (no es nuestro negocio), pero sin ese software no existe producto.

En cualquier caso de forma global las cuentas salen, pero siempre debemos estar trabajando en ajustar esos costes.

Por otra parte, el post intenta poner de manifiesto ese coste para crear conciencia sobre el y que no sea tan fácil olvidarlo :)