Este artículo es una traducción autorizada de un fragmento del post “Why You Shouldn’t Hire More Developers” (en caché) de Ash Moran publicado el 3 de Febrero de 2012 en PatchSpace Blog, y al que desde aquí agradezco el permiso y la disposición para publicarlo en Navegápolis.
La situación latente
Eres responsable de un equipo de cinco programadores, y estás completamente quemado. Pasáis los días en la oficina desde primera hora de la mañana hasta el final de la tarde, intentando hacer frente a una acumulación continua de trabajo.
De hecho empiezan a ser mejor las noches para trabajar, porque durante el día estáis inundados con interrupciones, emergencias y errores que reclaman atención, por lo que cada vez tenéis menos tiempo para desarrollar funcionalidades nuevas.
Casi no puedes atender a los clientes actuales, y los de comercial acaban de cerrar el acuerdo con un nuevo cliente, que tiene un montón de peticiones. Cada vez pierdes más tiempo en reuniones tratando de mantener la situación bajo control. Probablemente ya te estás tirándo de los pelos, pensando que no tienes tiempo para todo y que tienes que tomar una determinación.
Así que esbozas la situación en una hoja: Cada programador dedica al menos 60 horas a la semana, así que tienes unas 300 horas/programador por semana, de las que estimas que unas 50 se les van en corregir errores, otras 30 en atender la operativa del sistema y 20 en reuniones. En total 100 horas: ¡una tercera parte del tiempo! antes de poder atender las funcionalidades nuevas que están en un backlog que no para de crecer. ¡Y ahora para colmo un nuevo cliente!.
La conclusión es obvia: hay demasiado trabajo, y tienes desbordado todo el tiempo disponible, así que necesitas más gente. Si tuvieras dos programadores nuevos se podrían dedicar a la corrección de errores, a las cuestiones operativas e incluso podrían pellizcar algunas de las funcionalidades nuevas. Sólo tendrías que pagar por 40 horas semanales de cada uno, y como siempre, en cuanto asuman la cultura de la empresa acabarán dedicando más. Así que la solución es obvia, y vas a tu jefe para que autorice una selección de personal.
Mal. Lo último que deberías hacer en una situación como esta es contratar nuevos programadores.
La nueva contratación aviva el fuego
Tu nueva desarrolladora, Alice, empieza un lunes. Ella mantiene ocupado a un programador del equipo durante todo el día, instalando parcialmente su máquina. El martes sigue por su cuenta porque todo el mundo está en una reunión y tiene que pasar la tarde descifrando lo que hizo porque resulta estás utilizando una versión personalizada de una herramienta. Bob lo sabía, pero se olvidó de documentarlo porque en algún momento del mes pasado fue… convocado a una reunión con poca antelación. El miércoles dejas que Alice se encargue de una tarea sencilla de corrección de errores. Le lleva todo el día aprender a navegar por el código, pero lo confirma y sigue adelante. El jueves y el viernes lo pasa intentando implementar una de las funciones fáciles del backlog, pero más de la mitad del tiempo lo pasa con otro desarrollador porque apareció un viejo error. (Puede que esté en el rastreador de errores, pero desde que llegó a los 200 tickets abiertos, ya nadie lo revisa realmente). En fin, pasa la semana, y el trabajo sale en un despliegue el viernes por la tarde.
Llega el fin de semana. Todos han aprendido a desconectar durante el fin de semana, las horas extras aún no se han colado.
El lunes es un caos. Alice cambió algo que pensó que era un error, pero en realidad era un oscuro caso una regla de negocio. Nadie lo revisó porque estuvieron ocupados ayudándola a su instalación ¡y todo el mundo sabía que era fácil de todos modos! Así que hay que deshacer el despliegue. La conversación revela rápidamente que la característica que Alice comprometió el viernes fue un malentendido de las reglas de negocio. Ahora alguien del equipo tiene que hacer una revisión exhaustiva del código. Incluso sin contar con las horas dedicadas a esto, está claro que el equipo está significativamente atrasado, y en una base de código grande o compleja, no hay razón para creer que esto mejorará pronto.
¿Es todo culpa de Alice? ¿Podría haberse esforzado más? ¿O es el sistema el que tiene la culpa?
El cuello de botella
¿Qué es lo que estrangula el rendimiento de esta empresa? Está claro que no es el marketing: están trayendo clientes más rápido de lo que se puede desplegar el software. Y no es en el análisis: los requisitos se acumulan más rápido de lo que los desarrolladores pueden convertirlos en código. (Ni siquiera se trata de operaciones: el trabajo de una semana salió el viernes por la noche y, aunque rompiera las reglas de negocio, era operativo. Eso nos deja con el cuello de botella directamente en el desarrollo. Así que si el desarrollo es el cuello de botella, ¿por qué fue un error empezar a contratar desarrolladores, para aumentar la capacidad de esta habilidad sobrecargada?
Los supuestos que subyacen a la contratación
Para explicar esta situación voy a explicitar algunos de los supuestos tácitos que a menudo subyacen a la contratación en un equipo con exceso de trabajo. Este es un punto crucial, ya que gran parte de la mentalidad compartida en las organizaciones de software es tácita, e influye en las decisiones sin que se rindan cuentas. Es comparable a la diferencia entre el trabajo invisible y el trabajo visualizado, por ejemplo, en un tablero kanban. (Hay que tener en cuenta que incluso las organizaciones que utilizan tableros kanban suelen tener otro tipo de trabajo no visualizado). La siguiente lista no es exhaustiva, pero servirá para entenderla. Muchos equipos actúan como si lo siguiente fuera cierto
- Los desarrolladores son fungibles
- La productividad es proporcional a las horas de los desarrolladores
- Arreglar los errores es valioso
- Los requisitos son todos necesarios
Los desarrolladores son fungibles
Tom deMarco llama a esto El mito del recurso fungible (en Slack). Muchos trabajos en fábricas y almacenes son en gran medida fungibles, en el sentido de que el tiempo para llevar a alguien a la plena productividad es intrascendente (horas o días). Esto no es cierto en el caso del desarrollo, donde incluso si un nuevo empleado conoce el lenguaje de programación, el marco de trabajo e incluso el dominio genérico de la empresa, todavía tardará mucho tiempo en que el conocimiento tácito de la base de código fluya en su cabeza.
No creo que los desarrolladores crean realmente que son fungibles (al menos, ninguno de los que he conocido lo diría), pero he visto equipos que contratan como si esta suposición fuera válida. Cada vez que se actúa como si un nuevo desarrollador que trabaja solo fuera a aumentar inmediatamente la productividad del equipo, se está actuando como si fuera cierto. Esta suposición tácita está en contradicción con lo que la mayoría de los desarrolladores declaran explícitamente que es la naturaleza de su trabajo. En una contradicción, en el mejor de los casos una de las partes tiene razón.
La productividad es proporcional a las horas de trabajo del desarrollador
Hay dos formas de esta suposición: en primer lugar, la idea de que un desarrollador que trabaja 10 horas diarias será un 25% más productivo que un desarrollador que trabaja 8 horas diarias; en segundo lugar, la idea de que un equipo de 10 desarrolladores es un 25% más productivo que un equipo de 8.
Para abordar la primera, recuerde que la naturaleza del desarrollo de software es la creación de nuevos conocimientos, lo que expliqué anteriormente en el post ¿Por qué los desarrolladores no pueden estimar el tiempo? Una consecuencia de esto es que el desarrollo es una tarea creativa que implica tomar constantemente decisiones lógicas. (Por ejemplo, ¿es el momento de dividir este largo bloque de código? ¿Utilizar XML o JSON? ¿Reemplazar el marco de la aplicación?) Como se explica en el artículo ¿Sufres de fatiga por las decisiones?, el cerebro humano tiene una capacidad limitada para tomar este tipo de decisiones y, una vez cansado, tomará atajos. La sensación de “sólo quiero irme a casa” puede estar provocando la introducción de errores. Por lo tanto, utilizar las horas extras como prueba de que el equipo tiene muy poca capacidad está en contradicción con lo que muestran los estudios científicos. El hecho de que una de las partes de esta contradicción pinte una imagen de heroísmo de los desarrolladores no la hace más cierta.
La segunda forma de la suposición de productividad-tiempo se basa en la idea de que la productividad de un equipo se escala linealmente. Esto no es cierto por la sencilla razón de que la complejidad en la gestión de un equipo no es el número de personas involucradas, sino los caminos y la cantidad de comunicación que implica. Comparemos, por ejemplo, lo fácil que es conseguir que 50 personas se pasen una pelota por una línea, frente a conseguir que incluso 5 personas se pongan de acuerdo sobre el menú de una comida en un restaurante chino.
Arreglar los errores es valioso
Los errores son, por definición, algo que el sistema no estaba previsto que hiciera. Hay ocasiones en las que nadie sabe si una idea funcionará (este es el reino del Lean Startup). Pero hay muchos, muchos defectos en el mundo en los que los desarrolladores tenían, en el momento en que escribieron el error en el sistema, el conocimiento para determinar que el comportamiento era incorrecto, pero por alguna razón no lo hicieron. Imagina que has llevado tu coche, por lo demás inmaculado, a que le cambien los frenos y cuando lo conduces después empieza a tirarse hacia un lado. ¿Qué valor le daría a que le volvieran a alinear las ruedas, incluso si lo hicieran gratis?
Cuando se solucionan este tipo de errores, lo que se hace en realidad no es trabajar, sino volver a trabajar. El desarrollador debe cargar en su cabeza el conocimiento de ese trozo de código, incluidos los requisitos, la forma en que se implementa, las dependencias que tiene, y luego hacer el cambio. Incluso en el caso de que la corrección de errores sea puramente la adición de código, y no el cambio de código existente, el desarrollador debe repetir el proceso de comprensión del subsistema para hacer esa adición. Cuando un nuevo desarrollador hace esto, puede tener que aprender desde cero toda un área de código, junto con cualquier conocimiento tácito necesario para ello, y luego cruzar los dedos para no romper nada (si un conjunto de pruebas detecta un error aquí, ese conocimiento ya se ha hecho explícito). Si la corrección de errores es un desperdicio, arreglar los errores introducidos mientras se corrigen los errores lo es doblemente. Yo lo llamo desarrollo “whack-a-mole”, un término que me entristece profundamente que aún no se haya puesto de moda.
Si tu equipo dedica una cantidad significativa de tiempo a corregir errores, tiene mucha más capacidad de la que crees. Eso no quiere decir que sea una reserva fácil de aprovechar, pero está ahí. La actitud de que los fallos son inevitables es perjudicial, ya que dará fuerza a la suposición tácita de que arreglar fallos es valioso.
Los requisitos son todos necesarios
He dejado esto para el final, ya que tiene una naturaleza diferente a la de los otros supuestos: implica necesariamente decisiones tomadas fuera del equipo de desarrollo. A menos que el equipo esté haciendo el software enteramente para ellos mismos, alguien más estará involucrado especificando el trabajo de desarrollo que se está haciendo. Si resulta que el 30% de las características de su software no se utilizan nunca o son innecesarias, entonces al menos el 30% del tiempo de desarrollo es pura pérdida. (Puede ser más, debido a la complejidad de la gestión de una base de código mayor, y al desperdicio debido a los errores en el código sobrante). Sin embargo, como muchos equipos están obligados por contrato a entregar una especificación fija sin referencia al valor de las características de esa especificación, esta puede ser una fuente de desperdicio difícil de solucionar. Por ello, no diré mucho más al respecto. En cualquier caso, suele ser más fácil conseguir que alguien limpie su caseta de jardín si antes puedes demostrar que eres capaz de mantener ordenada tu habitación.
La realidad del equipo ocupado
Recordemos que vinimos aquí porque Alice fue contratada para aumentar la capacidad de un equipo “sobrecargado”. Sin embargo, hemos visto que los supuestos en los que se basaba la necesidad de contratarla eran falsos:
El equipo no está funcionando a plena capacidad, está gastando al menos el 25% de su tiempo en retrabajo y mantenimiento evitable, incluso teniendo en cuenta las horas extras.
El equipo ni siquiera está produciendo la máxima calidad dadas las habilidades existentes en el equipo, porque algunos de los errores se introdujeron debido a que los desarrolladores estaban fatigados y estresados.
No se puede contratar a Alice para dar un alivio inmediato, porque la sobrecarga de la comunicación en realidad reduce la productividad al menos a corto plazo
Una nota sobre el tamaño de los equipos
Puede que tengas una reserva válida sobre mi atrevida afirmación de que no deberías contratar más desarrolladores: aumentar la capacidad no es la única razón por la que puedes querer hacerlo. Una muy válida es la redundancia, ya que los equipos muy pequeños son vulnerables a la Ley de Murphy. Si tu único desarrollador es atropellado por un autobús, tu proyecto está en peligro inmediato. (Por otra parte, es posible que un equipo de 10 personas sea devastado por un solo incidente con un autobús errante, si el equipo ha formado silos de conocimiento.
El artículo de Christopher Allen The Dunbar Number as a Limit to Group Sizes (El número de Dunbar como límite del tamaño de los grupos) explica algunas de las consecuencias de los distintos tamaños de los equipos.
Sin embargo, los equipos de pequeño tamaño pueden ser un riesgo menor del que parece. En mi experiencia personal, los desarrolladores rara vez son atropellados por los autobuses. Y es muy raro que se vayan por el sueldo. Pero los desarrolladores se marchan con mucha frecuencia debido a unas condiciones de trabajo insatisfactorias. Si eres el gestor de una situación como la de la historia, es probable que uno de ellos te lo haya dicho, con otras palabras.
También hay otra situación en la que podrías querer aumentar el tamaño de tu equipo: cuando la persona que incorporas tiene los conocimientos y la experiencia necesarios para ayudar a mejorar la eficacia de los demás. En este caso, sin embargo, sus responsabilidades tendrán que ir mucho más allá del puro desarrollo.
Qué hacer
Lo primero es dar un paso atrás y comprobar si se trata de resolver un problema causado fundamentalmente por un despilfarro sistemático dedicándole más esfuerzo. Esto es como poner más marineros en el servicio de achique cuando el ingeniero del barco debería estar soldando el casco. Fred Brooks enunció la Ley de Brooks hace más de treinta años: “Añadir mano de obra a un proyecto de software tardío lo hace más tardío”. Por favor, no ignore el pasado a menos que quiera convertir su oficina en una recreación histórica. Alguien me ha dicho personalmente: “¡Tenemos un gráfico perfecto que muestra la disminución de la velocidad cuando empezamos a añadir más gente!”.
Mejorar la productividad de un equipo de software es difícil. Implica entender el negocio, el equipo, la historia, los obstáculos que bloquean el progreso. Es un problema complejo y sensible al contexto. Al tratarse de una entrada de blog, que ya necesita un resumen TL;DR, me limitaré a señalar la dirección de un cuerpo de conocimiento adecuado, y a sugerirle que lea La Meta.
Vemos el mundo filtrado por las metáforas que tenemos. The Goal (de Eli Goldratt) muestra cómo nuestras suposiciones comunes nos ciegan a las verdaderas causas de los problemas a los que nos enfrentamos cada día. Ha vendido millones de ejemplares, se ha utilizado en miles de empresas y se enseña en cientos de colegios y universidades. La meta es el libro arquetípico sobre cómo centrarse en lo que importa. Sólo le llevará un par de días leerlo, y le enseñará a ver el verdadero origen de los cuellos de botella en su organización. (Este no es un enlace de afiliación).
Terminaré con una regla general: cuando te enfrentes a una situación como la descrita anteriormente, intenta explotar lo que ya tienes antes de dedicar más esfuerzo y dinero al problema. A menudo te darás cuenta de que puedes ser más eficaz con las personas y los recursos que ya tienes, una vez que descubras la verdadera razón por la que las cosas van mal.