Friday, September 18, 2015

Podcasts/talks. Emptying the queue (II)

I continue empting the talks queue... Here is another small batch of interesting talks:

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.