Hace unos días mantuve una interesante conversación con Nito Martínez, uno de los gerentes de Qindel. Hablamos sobre por qué muchos proyectos ágiles son tan caros a pesar de estar (aparentemente) bien gestionados. Nito me contó algo que de alguna forma yo ya sabía, pero él me lo explicó con una lucidez que yo no había sido capaz de conceptualizar. Este artículo contiene partes de la conversación y extensiones adicionales mias.
Actualmente casi todos los proyectos se gestionan con algún tipo de Metodología Ágil. Con estas metodologías, la fuente principal de retrasos y sobrecostes son los tiempos de espera y las tareas que están bloqueadas. Cuando no se hacía Agile sino que los proyectos eran subcontrataciones waterfall a precio y plazo cerrado, curiosamente los bloqueos no eran tan importantes porque el proveedor típicamente tenía varios proyectos en curso y cuando una persona se quedaba bloqueada en un proyecto simplemente se ponía con una tarea de otro proyecto. El uso de recursos compartidos entre proyectos generaba impredictibilidad sobre su disponibilidad y eventualmente los clientes acabaron exigiendo exclusividad y dedicación plena de los recursos. Por consiguiente, en lugar de ofrecer precio cerrado, los proveedores tuvieron que cambiar a cobrar por hora con el taxímetro puesto (time & materials). El time & materials es más barato para el cliente sólo si todo el mundo está ocupado todo tiempo. Pero más caro si los recursos están ociosos, ya que el cliente tiene que pagarles por hora igualmente.
Lo que sucede es que si se mira el estado de un proyecto ágil en una herramienta como JIRA (o la que sea…) es habitual encontrar que no menos del 25% de las tareas están bloqueadas y no se pueden acometer. Como otro de los principios del agilismo es reducir el número de tareas de curso (Work In progress – WIP) entonces un 25% de tareas bloqueadas implica que hay un considerable porcentaje de gente cruzada de brazos. Las metodologías ágiles ponen énfasis en la necesidad de evitar los bloqueos pero no explican operativamente cómo desbloquear tareas.
En el desarrollo de software, una tarea puede estar bloqueada esencialmente por cuatro motivos:
1º) porque depende de otra tarea previa que no ha sido completada.
2º) porque una etapa en la cadena de producción está saturada y la tarea está esperando a que haya recursos disponibles.
3º) porque el programador no sabe cómo realizarla.
4º) por motivos políticos, gerenciales, legales, etc.
A continuación enumeraré algunas tácticas posibles para evitar cada uno de estos tipos de bloqueo.
Desbloqueo por autoservicio
En software, la forma más fácil de desbloquear una tarea que está esperando por otra es que la persona a la espera pueda completar la tarea anterior. Por ejemplo, si un documento de arquitectura técnica está incompleto, el programador debería ser capaz de completarlo él mismo. Si hay que abrir un puerto en un firewall para conectarse con un servicio externo, el programador debería poder hacerlo por sí mismo (e informar al administrador del sistema, por supuesto). La evolución de la programación es hacia entornos donde todo, incluída la infraestructura, es programable. Así, el programador puede crear una máquina virtual o definir una topología de red, todo por software sin necesidad de depender de un administrador de sistemas. Excepto en el entorno final de producción, los programadores deben tener el máximo grado posible de libertad para moverse. Para que esta “anarquía de los programadores” sea factible han de cumplirse dos requisitos ineludibles: 1º) todos los cambios deben ser fácilmente trazables y 2º) debe ser posible revertir fácilmente un cambio.
Desbloqueo por redistribución de recursos
La tendencia actual para evitar que las tareas se bloqueen en un tablero Kanban es crear equipos multifuncionales integrados en lugar de departamentos cada uno encargado de una etapa. Esto sólo funciona cuando el espectro de habilidades de cada miembro del equipo es amplio. Si existe un equipo de front-end y un equipo de back-end y los de back-end bloquean a los de front-end, o viceversa, no sirve para nada crear un equipo mixto con un programador de front-end y otro de back-end pues será aún peor debido a que con los departamentos al menos existe un pool de recursos pero en una cadena de producción con sólo dos personas es facilísimo que una acabe esperando por algo que tiene que hacer la otra.
Desbloqueo de los tiempos muertos de los programadores
Un tipo de bloqueo que no se suele tener en cuenta es el tiempo que pasan los programadores averiguando cómo hacer algo, ocupándose por WhatsApp de alguna cosa no relacionada con el trabajo o consultando el menú del restaurante antes de salir a comer.
En ingeniería aplicada la inteligencia es menos útil de lo que podría parecer a primera vista porque muchos de los problemas en los que se pierda más tiempo son de descubrimiento de funcionalidad y parametrización. Basta hacer un pequeño estudio de la cantidad de horas que los programadores pasan en StackOverflow para percatarse de que sus desafíos diarios tienen bien poco que ver cón su capacidad para definir abstracciones o implementar algoritmos, sino que la mayoría del tiempo se pierde en averiguar qué valores de entrada necesita una herramienta, o dónde hay un defecto software, o cual es la forma correcta de la cadena de conexión a una base de datos.
La programación por pares es la forma más eficaz de reducir los tiempos muertos de los programadores, principalmente por los siguientes motivos:
1º) Cuando dos programadores trabajan juntos en la misma tarea es menos probable que se queden bloquedas en un punto ciego.
2º) Cuando dos programadores trabajan juntos en el mismo diseño e implementación es menos probable que haya que cambiarlo a posteriori.
3º) Cuando dos programadores trabajan juntos es más difícil que se distraigan con su Whatsapp o saliendo a fumar.
4º) Cuando dos programadores completan un entregable juntos no es estrictamente necesario llevar a cabo una revisión posterior que tendría que esperar a que un tercer programador, que en principio no sabe nada del entregable, esté disponible.
La programación por pares es un arte en sí mismo. Pocos equipos la hacen porque pocos gerentes creen realmente en ella y porque pocos programadores están psicológicamente preparados para programar en pareja. Además yo no me he encontrado dos equipos que la hagan igual. Y para colmo, algunas de las recomendaciones de su práctica ortodoxa, como por ejemplo que el controlador y el navegador cambien de rol con frecuencia, en mi experiencia resultan en un puto desastre.
Desbloqueo de motivos políticos
Nada se puede hacer en un proyecto donde no hay voluntad política de hacer algo. Esto no es algo que se pueda solucionar a nivel operativo o táctico. Normalmente lo que sucede es que la gente tiene miedo de ser hallada culpable de haber cometido algún error o haberse saltado algún procedimiento. Por lo que sé, esto es especialmente cierto en los países anglosajones donde los compañeros de trabajo se pasan el día buscanndo dónde pueden pillar a otro. Microsoft llegó a hacerse tristemente famosa por su nefasta política de recursos humanos basada en un «diezmo romano» mediante el cual los programadores que no alcanzaban el nivel del equipo eran sistemáticamente despedidos. Esto condujo a grupos de programadores que estaban más preocupados por no quedar los últimos de la lista que por hacer nada producitivo y muchísimo menos arriesgarse ha hacer algo que pudiere fallar.
CAPEX vs OPEX en la asignación de recursos
Casi todas las empresas tienen dos tipos de costes informáticos: los costes fijos operacionales mes a mes (OPEX) y los costes variables soportados por una contrapartida de ingreso de un cliente (CAPEX). En servicios informáticos, el coste variable no importa siempre y cuando se le pueda aplicar un margen de al menos un 40%. Es decir, si se lo pueden repercutir al cliente final entonces a los proveedores les da igual cuánto se tengan que gastar en proveedores y subcontrataciones. Lo que no le da igual a los proveedores de informática (ya sean externos o departamentos internos) son sus costes fijos de operaciones. Entonces tratan de minimizar los costes fijos.
Esta razón financiera ha creado dos grandes grupos de informáticos: la «tropa regular» (OPEX) y los «mercenarios» (CAPEX). Como los esfuerzos para ahorrar costes se concentran en OPEX, frecuentemente los servicios de operaciones y administración se convierten en un cuello de botella porque están infradimensionados con respecto a las necesidades que los equipos de desarrollo cuyo coste es directamente repercutible a un cliente.
Conclusiones
La autogestión de equipos ha sido un salto cualitativo hacia adelante en la productividad y la predictibiliad, pero no basta por sí misma. Es preciso evolucionar de los equipos autogestionados a los equipos verdaderamente autosuficientes. La forma más sencilla de conseguir esto es eliminar dependencias de terceros. Los tiempos muertos que afectan a la productividad no sólo se encuentran en las uniones entre eslaboles de la cadena de producción sino que pueden estar dentro de alguno de los eslabones. Por consiguiente, es necesario optimizar tanto a nivel global como microgerencial.
Post relacionados:
Teoría de Restricciones aplicada al desarrollo de software.
Las zonas grises de Agile.
Muerte por agilismo.
Metodologías basadas en la gestión de expectativas.