¡ Oh no ! Otro post infumable sobre equipos de desarrollo… Si señores y señoras vuelvo a la carga con este tema que considero de importancia vital, no os preocupéis creo que es el último de la serie. Considero importante este tema porque si no tenemos un equipo bien estructurado lo tendremos muy difícil para tener éxito en nuestros proyectos.
En mi anterior post sobre equipos comenté que una estructuración plana y democrática era la más ágil y óptima para el desarrollo de software. Sin embargo al crecer en tamaño dicha estructura se colapsa debido a la sobrecarga de información de cada miembro del equipo. Además para explotar las ventajas de tal estructura de equipo lo mejor es que estén todos colocados en la misma sala. Esto nos lleva a un problema, ¿qué hacemos si necesitamos un equipo muy grande (más de 9)?¿Qué hacemos si no tenemos a todos lo miembros del equipo colocado? En estos casos necesitamos estructurar el equipo de forma diferente. Veamos alternativas.
La primera tentación es montar una jerarquía. Ciertamente las jerarquías disminuyen la cantidad de lineas de información que llegan a una persona, lo que permite que esta se sature menos si el equipo es grande. Desde este punto de vista los equipos organizados en jerarquías escalan bien con el tamaño. De hecho el número de lineas de comunicación crece mucho más despacio (logarítmicamente) que con equipos planos (crecimiento lineal). Otra ventaja es que la toma de decisiones la toma el jefe, lo que permite mayor velocidad de decisión que la basada en consenso. Es la forma tradicional de organizar los equipos. Todo parece bonito pero… esta estructura ¡no es ágil! y además ¡ es frágil ! Veamos:
- Frágil. La estructura depende de las personas que son jefes de equipo. Con suerte puedes tener un jefe que sepa lo que hace y sea competente, si no tienes tanta suerte te toca un jefe que es una nulidad. Cuanto más arriba en la jerarquía esté la persona, más vital es. Un equipo plano es más robusto ya que no depende de una sola persona.
- No ágil. Cada miembro del equipo no tiene una linea de comunicación con sus compañeros sino con su jefe. Si una información necesita pasar desde una persona a otra, no puede hacerlo directamente, sino que debe pasar por al menos un jefe o más. Por cuántos intermediarios pase depende de la «distancia» entre las dos personas, si están en el mismo equipo pasan por un sólo jefe, si están en equipos organizatívamente lejanos pasa por varios intermediarios. De hecho el número máximo de intermediarios crece logarítmicamente con el tamaño del equipo mientras que en un equipo plano se mantiene constante en cero. Paradójicamente, esta estructura hace que los jefes más importantes, los que deben tomar decisiones vitales, reciben la información más anticuada y desvirtuada ya que son los que tienen siempre más intermediarios con la realidad.
- No favorece el espíritu de equipo y colaboración sino la competencia entre jefes y la «política».
Evidentemente este modelo radical de jerarquía no suele aplicarse. Es más común el tener pequeños grupos planos que están coordinados por un jefe. Esto disminuye un poco el problema pero no lo elimina por completo, sobre todo si tenemos en cuenta que los equipos planos están en la base, y que es más raro encontrar equipos planos de jefes.
Otra forma típica de estructurar un equipo es alrededor de especialistas. Se suelen tener grupos de especialistas, donde cada grupo es experto en un componente del sistema o en una tarea o actividad. La idea detrás de esto es que los especialistas son muy eficientes en realizar unas actividades en concreto, por lo tanto la forma más eficiente de organizar un equipo es que cada individuo o grupo haga lo que mejor sabe hacer, su especialidad. De esta forma el rendimiento del equipo de desarrollo será óptimo, ¿verdad? Pues no, ¡ FAIL ! Veamos el siguiente dibujo ilustrando un equipo basado en especialistas:
Como se ve desde que una historia de usuario se extrae del product backlog hasta que se completa y reporta un valor al cliente (y dinero para nosotros), ésta pasa por… ¡un montón de intermediarios! Cada intermediario (especialista) de nuevo añade un posible punto de encolamiento («el otro equipo está tardando mucho en darme trabajo, yo no tengo la culpa….») y de malentendidos («pero suponíamos que la interfaz entre el componente A y el componente B era así, no nos la explicásteis bien»). El hecho de que cada grupo sólo entienda de su especialidad agrava los problemas, ya que provoca entre otras cosas:
- Cada uno intenta optimizar el proceso global y el código desde el punto de vista de su especialidad sin tener en cuenta el objetivo global. Esto produce optimizaciones locales que no son eficientes. Por ejemplo un desarrollador puede decidir escribir código sin pruebas rigurosas, lo que optimiza su trabajo (acaba antes) pero genera un problema en el equipo de control de calidad.
- Crea rivalidades y evita el espíritu de equipo. Cada grupo tiende a ver a los demás como «tontos» que no entienden su trabajo (especialidad).
- No se produce una diseminación del conocimiento entre los distintos empleados. Cada uno se queda «encasillado» en su especialidad para siempre.
- No hay un feedback rápido ante problemas. Un problema introducido por un equipo puede no ser detectado hasta que llega a otro equipo, potencialmente alejado.
- Como normalmente los equipos de especialistas no colaboran entre si, se necesita la figura de un coordinador.
- Normalmente llega a una utilización ineficiente de las personas. No todas las «historias de usuario» tienen que necesitar de todos los especialistas. Si en un momento dado sólo hay historias de usuario que necesitan a los especialistas A, C y D, el especialista B se quedará desasignado. Esto es una consecuencia obvia de usar especialistas, los especialistas no son siempre asignables y pueden llevar a una utilización ineficiente de los recursos.
- El efecto «patata caliente» y «tu la llevas». Se suele echar las culpas a los demás equipos y pasarle el marrón al siguiente. Esto es debido a que cada grupo de especialistas no comparte una meta común con los otros grupos y además son incapaces de ver el proyecto en su conjunto, con tal de que su trozo esté terminado no les importa que el producto en global esté mal (la culpa será de los otros, mi parte está bien).
Como hemos visto la jerarquía y la organización en grupos de especialistas genera intermediarios y colas que son fuente de múltiples problemas. Por cada intermediario se produce un retraso, con lo que la información llegará más anticuada al receptor. Por cada intermediario hay una cierta de corrupción de la información y malentendidos, con lo que la información se perderá por el camino y lo que llegue al receptor no puede no ser lo suficientemente veraz o preciso. Si encima cada intermediario tarda una cantidad diferente y no predecible de tiempo en procesar la información se producirán encolamientos. Si quieres un equipo ágil, evita intermediarios. Las colas son también fuentes de ineficiencias. Por cada cola tenemos trabajo a medio hacer, parado que no genera valor. Por cada cola se retrasa el feedback, haciendo que un montón de posibles defectos y problemas estén escondidos, a la espera de aparecer en el momento más inoportuno y cuando todo el mundo está ya «en otra cosa». Si quieres ser lean debes evitar las colas.
Lo más eficiente es organizar los equipos grandes de forma que se minimicen el número de intermediarios y colas. Para esto tenemos dos armas: la autogestión y los equipos multidisciplinares. Veamos algunos consejos generales en este sentido:
- Organiza en equipos planos colocados en la misma sala a toda la gente que necesite comunicarse con mucha frecuencia y responder ágilmente. Equipos que no deban interaccionar tan a menudo pueden estar en otras salas o en centros remotos.
- Cada equipo debe ser multidisciplinar, debe tener varios especialistas. Además estos especialistas irán enseñando sus tareas a los demás miembros del equipo. Esto genera una transición gradual de especialistas a técnicos multidisciplinares y un mejor espíritu de equipo.
- Cada equipo debe tender a la autogestión, tanto de sus cometidos como a la interacción con otros equipos. Esto evita la figura del coordinador y aunque tengamos un coordinador su actuación no sea tan vital.
- Para coordinar varios equipos cada equipo puede nombrar a uno de sus miembros como representante. Este nombramiento puede rotar con el tiempo. Todos los representantes de todos los grupos se organizan de forma democrática y se reúnen periódicamente para discutir temas de organización.
- Cada equipo es responsable por entero de la entrega de la tarea que tiene encomendada. No se debe responsabilizar a individuos. Esto genera una meta común y une al equipo.
- De la misma manera todos los equipos son responsables del éxito o fracaso del proyecto en su conjunto.
- Mantén los miembros de un mismo equipo juntos durante mucho tiempo, de esta forma se conocerán entre si y su coordinación crecerá.
- De vez en cuando ofrece la posibilidad a los miembros de un equipo para cambiarse a otro equipo. Asi no se quemarán ni se cansarán del mismo ambiente y tendrás un nivel adicional de diseminación de información.
Si implementamos estos consejos podemos montar un equipo estructurado en base a «feature teams». En este tipo de estructura cada grupo o «feature team» se encarga de realizar una historia de usuario. Veamos el siguiente dibujo:
Como vemos eliminamos las colas. Cada equipo es multidisciplinar y tiene su propio Product Owner. De esta forma es capaz de coger una historia de usuario e implementarla sin necesidad de pasar por otros grupos. Como cada equipo es plano, éste se comporta de forma ágil y rápida. En la figura hay cuatro equipos, cada uno de ellos en su propia sala. Los equipo que pertenecen a «Color Features» están en el mismo edificio porque cogen historias de usuario que tienen bastante relación entre si, son funcionalmente próximas, por lo tanto los dos equipos necesitan comunicación ágil y por lo tanto proximidad. De la misma manera «Alpha Features» está en otro centro de trabajo y se estructura de forma similar. El uso de autogestión y representantes de equipos disminuye mucho la necesidad de coordinadores. Sin embargo siempre es bueno es tener varios scrum masters itinerantes o coachers que se dediquen a resolver dudas, aconsejen a los equipos, desatasquen potenciales problemas globales o arbitren en disputas «irresolubles». Estos «coachers» no serían coordinadores sino facilitadores y maestros. Tampoco es mala práctica que además del representante de equipo se reúnan periódicamente los product owners de cada grupo para mantener una linea de coherencia estratégica del producto.
Un hecho interesante es que como cada historia de usuario requiere de varias tareas o componentes para ser completadas, cada grupo debe trabajar sobre distintas áreas de código. Esto hace que todos los grupos tengan una responsabilidad compartida sobre todos los componentes de código de la aplicación. De esta forma a todos los grupos le convienen que todos los componentes de código estén hechos con una calidad y mantenibilidad decentes, porque te puede tocar usarlos o modificarlos para la siguiente historia de usuario. Contrasten este efecto con lo que ocurría con los especialistas, cada especialista sólo se preocupa de su componente y no de los demás. El hecho de que varios grupos modifiquen simultáneamente las mismas zonas de código nos genera un problema de gestión. Este problema se soluciona con varias prácticas del agilismo:
- Pair programming. Para aumentar la calidad del código (revisión continua) y la diseminación de la información (enseñanza mutua entre los miembros de la pareja).
- Repositorio de código con control de versiones y concurrencia optimista. Es vital que el sistema de control de versiones de código no bloquee los ficheros. Si los bloqueara se producirían encolamientos entre dos grupos que necesitan modificar el mismo componente de código.
- TDD. Para mantener una suite de pruebas que te permita tocar el código de otro sin miedo a romperlo y no darte cuenta.
- Integración continua. Para integrar de forma continua los cambios de los distintos grupos, disminuir la probabilidad de conflictos, y agilizar la fusión de versiones en caso de que los hubiera.
Finalmente, todo esto funciona porque los miembros de tu proyecto que necesitan una comunicación más rápida y ágil son los que están implementando una misma historia de usuario. Dos personas implementando dos historias de usuario distintas no tienen tanto acoplamiento y necesidad de intercomunicación como dos personas que están trabajando sobre la misma historia de usuario. De hecho el acoplamiento entre dos «feature teams» se produce sobre todo a través de la base de código compartido. En este caso dicho acoplamiento se puede optimizar mediante TDD e integración continua con lo cual no es necesario una intercomunicación tan frecuente. Dicho esto aprovecho para introducir una práctica muy necesaria en este escenario, pero tenida por no ágil: la documentación. Como vemos la comunicación se realizará de forma más intensa por código entre dos «feature teams» distintos, por lo que además del TDD y la integración continua es necesario reforzar el grado de legibilidad del código, y eso se hace precisamente con una buena documentación. Recordad que el agilismo no prohíbe la documentación, sólo dice que documentes lo justo y necesario. En proyectos grandes, la cantidad de documentación justa y necesaria es mucho mayor que en un proyecto pequeño. Si no vas a implementar TDD, integración continua y no vas a mantener una buena documentación, tus «feature teams» no podrán coordinarse con efectividad y tu proyecto fracasará.
Como conclusión: es posible gestionar proyectos grandes usando agilismo aunque nuestro equipo se muy grande o esté distribuido. Ciertamente no es el caso óptimo pero la realidad manda. Para afrontar esto hay que estructurar tu proyecto en múltiples equipos pequeños, colocados en la misma sala, multidisciplinares y autogestionados, donde cada equipo implementa una historia completa de usuario detrás de otra. Como sacrificio podemos hacer que cada equipo pueda estar en su propio centro de trabajo, pero la menor interacción entre dos «feature teams» hacen que el TDD, la integración continua y la documentación sean vitales. Como prácticas a evitar están la de estructurar en grupos de especialistas y minimizar el grado de jerarquía.