Feeds:
Entradas
Comentarios

Archive for abril 2010


Bueno, aquí sigo con la serie de posts sobre equipos de trabajo ágiles. Me voy a meter en un terreno más especulativo que en los posts anteriores. En éste y en los siguientes posts intentaré investigar y razonar como debemos configurar un equipo desde el punto de vista de su estructura o topología. El razonamiento lo haré desde la perspectiva de la toma de decisiones y la difusión de la información.

Partamos de la estructura más sencilla: un equipo sin estructura, en el que todos los miembros sean iguales, tomen las mismas decisiones y estén igual de informados que los demás. Llamaremos a esta estructura un equipo plano. La idea es que todos los miembros del equipo se comunican entre si de forma libre y van tomando decisiones individuales sobre la marcha. En la siguiente figura se muestra un esquema de como sería un equipo de este tipo con 5 miembros:

Equipo Plano

Equipo Plano

Los nodos representan miembros del equipo y los arcos líneas de comunicación posibles. Como se aprecia cada miembro del equipo tiene acceso directo a cualquier otro miembro, y no existen intermediarios innecesarios. Existen distintos modos de comunicación posibles:

  • Peer to peer. Existe un único emisor y un único receptor. Es la más simple. Un ejemplo sería una conversación privada o una llamada de teléfono.
  • Multicast. Se produce cuando la comunicación alcanza simultáneamente a un grupo escogido de miembros del equipo. Un ejemplo típico es cuando varios miembros se juntan y hacen una reunión, tal vez informal junto a la máquina de café.
  • Broadcast. La recepción de la información es global entre todos los miembros del equipo. Puede ser por ejemplo una comunicación general o un mail masivo. Un ejemplo de broadcast es la difusión de información mediante ósmosis. Ésta se produce cuando tenemos a todos los miembros del equipo en la misma sala, y la información se difunde simplemente interceptando los comentarios de la gente que te rodea, o sea, lo que siempre se ha llamado «enterarte de lo que se cuece».

Otro punto importante es que parte de la comunicación se realiza mediante señales no verbales, tales como gestos y expresiones faciales. Además el compartir un mismo contexto y entorno agiliza la transmisión de información. Es por esto que se recomienda como buena práctica ágil el tener a todos los miembros del equipo en la misma sala. Ésto va a facilitar la transmisión de información y la toma de decisiones. De hecho existe alguna buena práctica en este sentido como el radiador de información que consiste en tener un tablero o pantalla, bien visible, con información importante del proyecto (estado del build, grado de avance del proyecto, retrasos, etc). La ventaja de  la comunicación broadcast es su rapidez y que evita que se formen grupos de gente que no tengan información importante.

El punto de vista tradicional del agilismo, en lo que respecta a estructuración de equipos, consiste en tener un equipo de gente colocado en la misma sala, que aproveche los modos broadcast de comunicación tales como la ósmosis de información, reuniones diarias y usar técnicas como los radiadores de información. Hasta este punto todo parece sentido común, sin embargo la cosa no es siempre tan bonita como lo pintan. De hecho yo siempre me hago la misma pregunta, ¿cómo de grande puede ser un equipo con estructura plana? En la literatura ágil se suele dar una cifra de un máximo entre 9 o 12 personas. Pero, ¿por qué esto es así? ¿Cómo escala la productividad de un equipo plano en función de su tamaño?¿Qué pasa si realmente necesito un equipo de más de 12 personas debido al tamaño y tiempos de entrega de mi proyecto?¿Tendré que renunciar al agilismo en este último caso? Intentaré explorar estos temas.

Partamos de un modelo sobre como tomamos decisiones. No pretendo que sea un modelo exacto, pero si aproximado, y aunque no tengo datos cuantitativos reales, al menos puedo basarme en mi experiencia. Suponemos que tenemos un tiempo máximo para tomar una decisión, pasado ese tiempo la utilidad de la decisión se desvanece. Este tiempo máximo puede depender del tipo de decisión al que nos enfrentemos. Por ejemplo, si es una decisión de diseño de software podemos tener un par de horas de tope, o si es una decisión sobre como llamar a la siguiente clase que vamos a codificar podemos tener un tope de unos minutos. Para tomar decisiones necesitamos un flujo de datos entrantes que nos informen del estado del mundo. De ese flujo de datos debemos descartar lo que es irrelevante, la información duplicada, valorar posibles falsedades y errores en la información, etc. Esta tarea de filtrado normalmente la hacemos inconscientemente y no la percibimos. Mi idea es que cuanto más flujo de datos tengamos más tardaremos en tomar una decisión acertada. Veamos el siguiente gráfico:

Tiempo de decisión VS. flujo datos entrante

Tiempo de decisión VS. flujo datos entrante

Como vemos al principio nos llega poca cantidad de información, por lo que podemos filtrarla rápidamente, de hecho podemos filtrar y tomar la decisión antes de que nos lleguen más mensajes del exterior. A esta zona le he asignado un tiempo de toma de decisión constante, ya que no se nos «atasca» la información entrante. Si aumentamos el flujo de información vemos que cada vez nos cuesta más filtrar y separar lo que es importante de lo que no lo es, por eso el tiempo va aumentando. Tal vez no aumente linealmente como en la figura, pero aumentará. Sin embargo todavía podemos tomar la decisión antes de que el plazo expire. Finalmente llegamos a una zona donde simplemente no nos da tiempo de analizar todo ya que expira el plazo, en estos casos nos forzamos a tomar una decisión porque «no tenemos tiempo», decisión que tiene mayor riesgo de ser equivocada. Como siempre todo esto depende de la persona en cuestión que tome las decisiones, en función de experiencia y capacidad algunas personas podrán procesar la información más rápidamente que otras. De nuevos nos encontramos con una de las máximas del agilismo: los miembros de tu equipo deben tener talento, poténcialos.

Os estaréis preguntando que tiene todo esto que ver con la organización de un equipo. Muy sencillo, la forma en la que esté organizado el equipo impacta en como crece este flujo de información en función del tamaño del equipo. En el caso de un equipo con estructura plana, cada miembro recibe un flujo de mensajes de todos los demás miembros, por lo tanto el flujo de información entrante aumenta al menos linealmente con el tamaño del equipo. Si juntamos este hecho con el modelo presentado anteriormente nos damos cuenta que los equipos con estructura plana pierden eficiencia rápidamente conforme aumenta el tamaño de éste. En la siguiente figura podemos ver un esquema de como sería:

Productividad y eficiencia VS Tamaño de equipo

Productividad y eficiencia VS Tamaño de equipo

Conforme el tamaño aumenta, el flujo entrante de información aumenta igual de rápido, esto hace que el tiempo de filtrado de información aumente aún más rápido hasta alcanzar el límite de tiempo de decisión, a partir del cual la calidad de las decisiones degenera debido a las «prisas» y «sobrecarga» y la productividad del equipo disminuye. Cuando estamos todavía en la zona de carga baja añadir un miembro al equipo incrementa la productividad linealmente ya que el tiempo de filtrado sigue siendo constante. Cuando entramos en la zona intermedia, la productividad todavía aumenta pero menos, ya que el tiempo de filtrado de información va aumentando. Cuando alcanzamos la zona límite, donde no cumplimos con el tope máximo de tiempo, añadir un miembro más al equipo sólo empeora las cosas. Como vemos los equipos con estructura plana no escalan bien con el tamaño. Una forma sencilla de arreglar esto es poner personas con más capacidad en el equipo, pero esta medida tiene sus límites.

Otro tema a tener en cuenta es que si bien muchas decisiones son individuales otras conciernen al equipo y al proyecto en su conjunto. Las formas más básicas de tomar decisiones de equipo son las siguientes:

  • El jefe. Existe una persona con la responsabilidad y autoridad para tomar decisiones globales.
  • Comité de sabios. Un subconjunto pequeño de los miembros más expertos del equipo toma las decisiones.
  • Democracia. Se vota y gana la mayoría, ya sea simple o absoluta.
  • Consenso. Todo el mundo debe estar de acuerdo con la decisión.

Los modelos de democracia y consenso escalan mal con el tamaño del equipo. En un modelo de decisión democrático se genera un debate de cara a la votación, si el tamaño del grupo es grande se vuelve a producir la sobrecarga de información o bien el voto «desinformado». El modelo de consenso escala aun peor ya que cuanto más grande sea el equipo más dificultad existirá para poner de acuerdo a todos. Por otro lado en equipos pequeños estos modelos funcionan bien ya que aumentan la calidad de las decisiones y la moral del grupo.

El modelo del jefe puede minar la moral del equipo y puede ocurrir que la persona a cargo no tenga la capacidad necesaria para tomar las decisiones. También puede desembocar en dinámicas viciosas como la explicada en un post anterior. Es mejor escoger a alguien de mucha confianza y muy respetado para este rol.

En cualquier caso siempre es necesario, tanto para tomar decisiones individuales, como de equipo, que los miembros de éste tengan responsabilidad e iniciativa. Por otro lado, el tener especialistas, en vez de personas multidisciplinares en tu equipo, crea la dinámica de que cada uno toma decisiones para optimizar su «trozo de responsabilidad» y no el conjunto global. De hecho al ser especialistas y no entender el trabajo de los demás, son incapaces de tomar decisiones globales. Esto es especialmente importante si usas el modelo del jefe o de comité de sabios. Éstos deben ser responsables, multidisciplinares y tener iniciativa.

Con todo esto podemos empezar a entrever algunas guías para montar equipos con estructura plana:

  • Si puedes, coloca a tu equipo en la misma sala, aprovecha la ósmosis de información y usa radiadores de información.
  • Tu equipo no debe ser muy grande ya que sobrecargarás de información a los miembros de éste, y su eficiencia tomando decisiones disminuirá.
  • Contrata gente con talento para tu equipo, no solo serán más productivos, sino que admitirán mayor flujo de entrada de información, lo que permitirá que tu equipo escale mejor, pudiendo tener equipos grandes.
  • Los miembros del equipo deben ser responsables ya que sobre ellos recae el tener que tomar decisiones.
  • Monta equipos multidisciplinares, y si es posible que los miembros de éste también sean multidisciplinares. Ésto evita errores y habilita a más gente participar en la toma de decisiones globales al equipo.
  • Si el equipo es pequeño usa consenso o democracia, si ya tiene cierto tamaño es mejor un comité de sabios.

En la otra cara de la moneda, no deberías montar un equipo con estructura plana si:

  • Tienes un equipo distribuido en distintos lugares de trabajo.
  • El proyecto es grande y por lo tanto necesitas un equipo con un tamaño mayor al soportable por una estructuración plana.
  • Los miembros de tu equipo no tienen mucha experiencia o quizás les falta un poco de talento o responsabilidad.

Pero todos sabemos que a veces los proyectos son grandes, la gente no está en la misma sala o simplemente no tienen el nivel de responsabilidad o capacitación. ¿Qué hacemos? Si es un problema únicamente de responsabilidad y capacitación ve pensando en cambiar de miembros de equipo. Si es un tema de tamaño y localización piensa en cambiar la estructura de tu equipo. Este último aspecto lo exploraremos en futuros posts.

Read Full Post »


Continúo con la serie de post dedicado a la definición de equipos de desarrollos ágiles. En el anterior post hice un repaso general de malas prácticas y dinámicas sociales negativas que generan éstas. En éste veremos más en detalle los valores y características que debe tener un miembro del equipo para que éste sea eficaz.

Montar un equipo agile es más que incrementar la frecuencia de feedback, disminuir la burocracia y otras buenas prácticas. Lo más indispensable de todo es simplemente contar con la gente adecuada. No se trata de que simplemente pongamos un jefe de proyecto «buena gente» o de que tengamos programadores de alto nivel, sino de que todos los miembros del equipo, desde el primero hasta el último, jefes, técnicos y gerentes, compartan unos mismos valores y capacidades. Si hay una fracción significativa de los miembros del equipo que no cumplen ésto, simplemente fracasarás en tu intento de implantar el agilismo, uses las prácticas que uses.

El agilismo, en el fondo, propone un metaproceso capaz de adaptar el proceso de desarrollo en si, tanto a los cambios externos como a los errores detectados, con el fin de hacerlo cada vez más eficiente. Por lo tanto no nos vale con contar con gente capaz de seguir un proceso de desarrollo, sino que además deben ser capaces de mejorarlo de forma continua.  Ésto es vital, ya que aunque empecemos con un mal proceso, a través de la mejora continua podremos llegar a uno bueno. Si en cambio, empezamos con un proceso eficaz, y no tenemos capacidad de adaptación y mejora continua, simplemente ocurrirá que tarde o temprano nuestro entorno cambie y nuestro proceso ya no sea eficaz en el nuevo entorno, aunque lo fuera en el antiguo. Cada una de los valores que presentaré a continuación tienen pues como objetivo último, el capacitar a la organización para realizar una mejora continua del proceso de desarrollo, y adaptarlo a cambios en el entorno. Para cada uno de ellos indicaré ejemplos positivos y negativos:

  • Capacidad de aprender las habilidades necesarias para el trabajo. Una persona que tiene esta capacidad puede aprender por si mismo y de forma suficientemente rápida. En el extremo malo nos encontramos con personas que no quieren aprender, o sólo aprenden si reciben cursos. Esta habilidad es vital para poder adaptarse a nuevas tecnologías, métodos y circunstancias de forma rápida y eficaz.
  • Capacidad de detectar errores y problemas. La persona capaz de oler los problemas e ineficiencias, no solo en el código, sino en el proceso de desarrollo, son muy valiosas. Nos permiten reaccionar rápidamente para arreglar problemas, incluso antes de que estos produzcan daños. En el extremo malo encontramos personas que simplemente hacen sus tareas sin darse cuenta de los problemas, aunque se produzcan delante de sus narices ¿Alguien sabe leer una traza de una excepción?
  • Aprender de los errores. Equivocarse no es malo, lo malo es equivocarte y no aprender de ello, equivocarse una y otra vez en lo mismo. Ésto es propio de zombis no de personas.
  • Capacidad para enseñar a los demás. Esto es fundamental sobre todo en los roles de más responsabilidad. Un rasgo importante de un jefe eficaz y de un buen compañero es saber enseñar a los demás a hacer las cosas bien y a mejorar. Esto nos permite absorber a gente sin experiencia o incluso con malos hábitos y convertirlos en miembros del equipo productivos, te permite mejorar no a ti, sino a la gente que te rodea.
  • Capacidad de cuestionar las cosas de forma racional, incluyendo los modelos mentales ya establecidos. De esta forma simplemente seremos capaces de no quedarnos ciegos con modas y modelos mentales preconcebidos, impidiéndonos ver nuevas posibilidades y haciéndonos vulnerables al marketing. Ya hablé de esto en mi primer post.
  • Jugador de equipo. Los proyectos son realizados por equipos, no por individuos. Se necesita gente que mire por el conjunto del equipo y no solo por sus propios intereses, ignorando las necesidades del conjunto. Actitudes típicas tales como «el marrón es tuyo» o «balones fuera» son propias de gente egoísta y totalmente prohibidas en un equipo ágil. Todos deben colaborar para conseguir el objetivo común. Si no que se lo digan a algún que otro equipo de fútbol.
  • Iniciativa para ejercer todas las capacidades anteriores de motu propio sin necesidad de que alguien te lo ordene. Si no tienes iniciativa, a lo máximo que llegarás es a ser un burócrata que «hace su trabajo según el procedimiento», y eso con suerte. Esto es totalmente opuesto a la filosofía agile.
  • Motivación. Este factor es muy frágil y no depende totalmente de la persona, sino de su entorno. Si los compañeros juegan en equipo, los proyectos tienen éxito, aprendes y ganas un sueldo digno, tu motivación sube.

Aprovecho ahora para definir el termino calidad referida a una persona. Cuanto más y mejor cumpla una persona los valores y capacidades definidos anteriormente, diré de ella que tiene más calidad. No penséis que me refiero a su calidad como ser humano, sino a su calidad como miembro de un equipo que cobra por hacer un trabajo. Tampoco penséis que la calidad depende sobre todo de la experiencia o titulación de esa persona. Pensad que es mucho mejor contratar a alguien sin experiencia pero con capacidad de aprender y jugar en equipo, que a alguien de mucha experiencia sin estos valores. El primero aprenderá sobre la marcha, y cuanto más listo y experto sea, más rápido aprenderá, pero aunque no sea el más inteligente terminará aprendiendo. Por el contrario es muy negativo tener a un super experto pero que no juega en equipo, que no enseña a los demás, no colabora y echa siempre balones fuera.

Es importante detectar si la gente que ya tenemos cumplen estos valores, y si no los cumplen, diagnosticar por qué no. Tal vez sólo están inmersos en una dinámica negativa y no conocen otra cosa, pero pueden llegar a mejorar. O en el peor de los casos simplemente esa persona es incapaz de mejorar, en cuyo caso es mejor prescindir de ella.

Algunos estaréis pensando lo mismo que yo: en muchas empresas la política de contratación y RRHH es totalmente diferente, se basa en criterios como el sueldo, la apariencia o simplemente el azar. Todo esto forma parte de la dinámica negativa que comenté en el post anterior. En cualquier caso, nunca he visto a ninguna empresa completar los proyectos con éxito con este enfoque, aunque sí ganar dinero (usando prácticas poco éticas).

Por último sed indulgentes conmigo y permitid que me flipe un poco 😉 A continuación mostraré un gráfico sobre cómo evoluciona la productividad de un equipo en función de la calidad media de sus miembros. Por supuesto es un gráfico totalmente subjetivo y basado en mi experiencia. Para hacer uno objetivo tendríamos que poder tomar métricas sobre productividad del equipo y sobre la calidad de una persona, cosa que en si sería una tarea muy compleja. Sin embargo tras muchos años uno coge un feeling sobre como funcionan las cosas. Sin más preámbulos allá va:

Productividad en función de la Calidad Humana

Productividad en función de la Calidad Humana

Como veis tiene dos lineas: la del sentido común, y la que me dice mi experiencia. En la primera todo va como esperado, el aumento de productividad del equipo es lineal con respecto a la calidad de sus miembros. Sin embargo mi experiencia me dice que esto no es real. Si os fijáis en la otra serie, la productividad aumenta mucho más rápido en función de la calidad del equipo. Tal vez sea una aumento exponencial, ¡ o mayor ! Incluso puede llegar a producirse un efecto de discontinuidad: una persona de alta calidad será capaz de solucionar problemas que una persona de baja calidad sea incapaz de resolver, produciéndose en este caso un aumento infinito de la productividad (discontinuidad).

Como conclusión: si queréis montar un equipo eficaz, el primer paso es contar con la gente adecuada, mientras no consigais esto, no os molesteis en intentar otra cosa. Al fin y al cabo el proceso de desarrollo lo implementan y ejecutan personas, si éstas no son capaces, el proceso fracasará.

Read Full Post »


This blog is in Spanish but some readers have suggested me to translate the posts to english. In this way they will be in two languages, spanish (main) and english.

What do you think?

Read Full Post »


La idea para este post me la dio un comentario en el post de víctimas de la moda, alguien dijo que un arquitecto era visto como 5 programadores por parte de los gestores de proyecto. Ésto me hizo pensar en escribir una serie de posts abordando como se suelen montar los equipos de desarrollo y el efecto de éstos en el éxito de los proyectos. En este post daré mi opinión sobre los roles en un proyecto típico.

Muchas veces viendo como se organizan los equipos de desarrollo me da la impresión de contemplar un sistema social basado en castas, más propio de eras anteriores que de un entorno de alta tecnología. En mi opinión en muchos entornos empresariales los roles de los miembros de un equipo típico se asemejan más a clases sociales que a otra cosa. Esto es una tendencia muy peligrosa que hace que el equipo no actúe como tal, sino como una jerarquía señor/vasallo, y se transforme en varios grupos que desconfían los unos de los otros y se desprecien mutuamente. ¿Cómo se llegó a esta situación? Es difícil de saber, pero creo que hay varias causas:

  • El mal entendimiento por parte de los gestores en muchos clientes de lo qué es un proyecto software.  Ésto es comprensible ya que la mayoría de los clientes no saben construir software, no es su negocio, ¡ si lo supieran no necesitarían subcontratar ! Esta falta de entendimiento fue explotada por algunas empresas del sector, lo que ha creado desconfianza ¿Recordais cómo era todo antes del crack de las punto com…?
  • El concepto de gestor universal. Un gestor universal es alguien que cree que puede gestionar un proyecto de un área que no entiende usando herramientas genéricas. Tal gestor aplicará las mismas técnicas de gestión a un proyecto de software que a un proyecto de construcción de vivienda que a la organización de un equipo de administrativos. Obviamente esto es una concepción errónea que lleva al desastre. Si creemos en este principio terminamos con jefes de proyecto que no saben informática y que no se enteran de lo que ocurre de verdad en su proyecto.
  • Derivado del punto anterior nace la concepción errónea de que los informáticos son intercambiables, como si fueran piezas mecánicas de una maquinaria. Ciertamente esto puede ser real en otras áreas de gestión, pero no en la informática. El resultado típico es que los gerentes ven a los técnicos como simples obreros que no dan valor añadido y no son muy distinguibles de un administrativo, generando actitudes altivas y poco colaborativas y dialogantes. Además este prejuicio puede llegar a hacer que se considere que un técnico deba cobrar poco comparado con otros roles. Como reacción el técnico pensará mal del jefe de proyecto y lo considerará un opresor. Esta creencia es falsa, entre otras cosas porque un técnico tiene mucha información en su cabeza sobre el proyecto que uno recién llegado no tiene, y la productividad de los técnicos varía en función de su talento de una forma mucho más acusada a como varía ésta entre dos personas que realizan tareas mecánicas y repetitivas.
  • Carrera profesional. Como cada rol pertenece a una casta, es normal pagar más dinero a las castas más altas. Como la casta más baja es la de programador entonces será la que menos cobre. Te puedes encontrar con un jefe de proyecto sin nada de experiencia que cobre mucho más que un desarrollador con mucha experiencia y que produzca por diez desarrolladores normales. Lo que es peor, este desarrollador experto y talentoso tendrá un sueldo similar al de un desarrollador sin iniciativa ni talento. Esto hace que los desarrolladores se desincentiven, y no quieran seguir siendo desarrolladores, sino jefes de proyecto. Al fin y al cabo nadie va a reconocer nuestra capacidad como tales. Esto genera una dinámica que lleva a que escaseen los desarrolladores expertos y arquitectos, disminuyendo la calidad del equipo y aumentando la dificultad de contratar a un nuevo desarrollador que sepa lo que hace.

Todo esto puede generar dinámicas muy dañinas y un sistema de trabajo vicioso:

  • Alta rotación. Los miembros de las castas más bajas se sienten maltratados y deciden marcharse. Ésto genera a su vez que el conocimiento escape del equipo y la productividad baje. Como reacción el gerente para reemplazar esta baja puede decidir contratar. Como éste y RRHH no saben distinguir a un buen técnico de otro que no lo es, le resulta muy golosa la opción de contratar más barato. De esta forma podrá tener más miembros en el equipo con lo cual todo va a ser más productivo, ¿verdad? Y además al ser más barato se lo tendrá «menos creído y será más dócil». Total, tampoco es muy importante la cualificación, porque no es más que un «obrero». Para escribir en un teclado no hace falta saber mucho. Por este camino puedes llegar a terminar con un equipo bastante grande, lleno de gente sin capacidad técnica y/o sin iniciativa.
  • Sabotaje. El técnico está tan quemado que simplemente realiza código de baja calidad, no hace pruebas, copy&paste, etc. Al fin y al cabo al jefe de proyecto sólo le interesa llegar en fechas, y tener terminado tal funcionalidad para la reunión de seguimiento tal, que si no le riñe el cliente. Además el jefe de proyecto no es técnico con lo que no puede detectar estas malas practicas. El que se introduzcan defectos en el software no es evidente en el momento, lo que hace que el jefe de proyecto piense que todo va bien hasta que la situación explota.
  • Más madera. Como tenemos problemas, pongamos más gente. Hay que presionar a RRHH para que contraten rápido y barato. RRHH ante esa presión contrata rápido y barato, es decir mal. Tu equipo crece sin mesura y se llena de técnicos sin capacidad.
  • Zombis. Ya que contratamos barato, puedo convencer al cliente de que su proyecto va mal y necesita «más madera». Yo le vendo que le contrato 10 técnicos de los buenos más, a tarifa buena y contrato 10 cadáveres para que calienten la silla. Los cadáveres son baratos y el volumen del proyecto aumenta, con lo que es más rentable. Realmente esto es un técnica propia de consultoras sin ética ni escrúpulos, que es posible debido a que el cliente no sabe diferenciar entre zombis y desarrolladores.
  • Proyecto cerrado y horas extras como recurso común. La defensa del cliente ante «más madera» y «zombis» es cerrar el proyecto en tiempo y dinero. De esta manera no puede ser engañado por empresarios sin escrúpulos. Esto genera que cualquier sobrecarga de trabajo se termine ejecutando como horas extras y la consiguiente bajada de productividad y «quemamiento» del equipo, lo que aumenta la rotación.
  • Metodología pesada. Debido a «más madera», tienes un equipo muy grande. No sabemos como hacer que muchas técnicas del agilismo escalen bien a equipos grandes. Además los malos resultados del proyecto hacen que el cliente desconfíe. Como conclusión los gestores se sienten reafirmados en su metodología pesada, ya que el agilismo es «para proyectos de juguete» y «tenemos que controlar a todos estos sinvergüenzas».

Si pensáis que lo que cuento es una exageración, yo he conocido proyectos en los que los jefes de proyectos no sabían manejar un ordenador pero si hablaban un inglés de nivel. He visto zombis atestar salas de trabajo, sí, lo he visto en alguna gran consultora, aunque afortunadamente nunca he trabajado para ellos y no todas son tan malignas como las pintan.

Lo peor es que esta dinámica se refuerza a si misma con lo que es muy difícil de romper y se transforma en el modelo mental por defecto de las personas involucradas en la informática. Lo aceptan como una verdad evidente y no se plantean que las cosas pueden ser de otra forma y te dicen «olvídate del agilismo, es un cuento de hadas«. Cuando alguien llega nuevo a este negocio, los que ya están en él, y metidos en esta dinámica viciosa, te cuentan que las cosas son como son y que no se pueden cambiar. Que se contrata barato y mal porque no te puedes fiar de un desarrollador y el proyecto siempre se sale del presupuesto; que se hacen proyectos cerrados para que el presupuesto no se vaya de madre y no nos engañen; que te olvides del TDD que eso lo que hace es quitarte productividad y nadie te lo va a agradecer; que te olvides del pair programming, que lo único que hace es disminuir la productividad a la mitad, y encima cuando viene el cliente ve la mitad de sillas ocupadas… No se dan cuenta que esta dinámica ineficiente no es una propiedad intrínseca de los proyectos software sino causados por una mala gestión y por muchas concepciones erróneas. Ésto es una de las causas más importante de resistencia al agilismo, el pensar que el desarrollo de software es así y no se puede hacer de otra forma.

Precisamente en el agilismo se intenta eliminar este ciclo vicioso. Para ello usa diversas técnicas:

  • Tener una persona que actúe como puente entre el cliente y el equipo. Sepa defender los intereses del cliente pero de forma razonable e interaccione frecuentemente con el equipo. Debe filtrar y priorizar los requisitos del cliente y ser capaz de pasárselos al equipo. Es como tener un cliente a tu lado continuamente, es el Producto Owner.
  • Enseñar resultados frecuentemente al cliente. Resultados tangibles, demos, pruebas de concepto, prototipos, la aplicación parcialmente construida, etc. El cliente puede no entender de software pero si que va a entender la demo. Al permitir un mejor seguimiento, evita recelos por parte del cliente y aumenta la confianza con lo que la dinámica social del proyecto mejorará.
  • Persona que actúe como jefe de proyecto, actuando como enlace principal con el Product Owner, siguiendo el desarrollo del proyecto día a días, y encargado, de forma principal, de eliminar cualquier impedimento para el buen avance del proyecto. Al contrario que el jefe de proyecto tradicional, debe tener la suficiente capacidad técnica como para entender problemas de índole técnica, además de problemas organizativos. De esta forma será capaz de tomar decisiones cabalmente y detectar malas prácticas. Además debe hacer una labor de enseñanza del método de trabajo que se esté siguiendo. En SCRUM, por ejemplo, a este rol se le denomina Scrum Master.
  • Tener siempre en el equipo a un miembro de gran talento y experiencia que además de trabajar y producir en el día a día, se encargue de evitar pitfalls típicos, de plantear soluciones problemas difíciles y que actúe además como mentor del resto del equipo. Tradicionalmente lo más parecido a esto es un arquitecto. La diferencia está en que es un arquitecto que trabaja continuamente con su equipo, produciendo código y enseñando a los demás. No es alguien que aparece para arreglar un incendio y desaparece. Ni tampoco alguien que desprecia a los desarrolladores, se dedica a pintar cajitas y citar a gurús. Si la carga de trabajo lo permite, este mentor y el Scrum Master pueden ser la misma persona.
  • Motivar a los desarrolladores. Pagarles justamente y evitar horas extras como recurso común, escuchar lo que tengan que decir (daily meetings, retrospectivas, reuniones de planificación, …) Esto evita la rotación y aumenta el entusiasmo del equipo. También evita el cansancio de las horas extras.
  • Si se necesitan horas extras, que sea de forma excepcional, y que todo el mundo las sufra, desarrolladores, jefes de proyecto, etc.
  • Contratar a personal competente y eliminar de tu equipo a personas sin motivación para hacerlo bien y sin capacidad de hacer su trabajo. Esto normalmente implica hacer una buena selección de RRHH, lo que a su vez es incompatible con las prisas.

Un error común al implantar el agilismo es usar como Scrum Master a un jefe de proyecto con la mentalidad tradicional, y contratar como miembros del equipo a personas sin motivación y sin capacidad técnica. Esto hace que al final no se haga agilismo, por mucho que los roles parezcan ágiles. El desarrollador sin motivación y capacidad producirá poco, no escribirá código con calidad suficiente, no tendrá iniciativa, etc. El jefe de proyecto que siga pensando que está por encima del resto de los miembros del equipo y que no entiende el proyecto, generará la misma dinámica viciosa de siempre.

Otro error clásico es hacer que el Product Owner o no exista o sea el mismo jefe de proyecto. Esto es un error porque el primero representa al cliente y el segundo al equipo, si hacemos coincidir los dos roles en el jefe de proyecto corremos el riesgo de no atender a las necesidades y prioridades reales del cliente y caer en prácticas no éticas. Si hacemos coincidir ambos roles en una persona del cliente el proyecto se convierte en barra libre y nadie atiende a las necesidades y problemas reales del equipo.

En el fondo de todo esto está la enseñanza que creo más valiosa del agilismo: lo más crítico no es el proceso sino la gente que componen el equipo y dan vida a ese proceso. No gastes pues tanto en procesos, y preocúpate porque la gente que contrates sea apta para su puesto y sobre todo que sepan jugar en equipo, al fin y al cabo el desarrollo de software es un juego de equipo, no de individualistas.

Read Full Post »


Lo cierto es que una de las novedades que se introdujeron en la JDK5 que han causado mayor impacto son las anotaciones. Ahora la mayoría de los frameworks e incluso estándares JSR hacen un uso intensivo de las anotaciones, son algo que esta de moda. Están tan de moda que a veces las podemos llegar a usar de forma incorrecta sin darnos cuenta. Al fin y al cabo se usan por todos lados, y si algo se usa mucho entonces es que esta bien, ¿verdad? Debemos descubrir cuando usarlas y cuando no, y de eso precisamente, hablo en este post.

Ciertamente las anotaciones resultan muy útiles y nos proporcionan una herramienta muy potente a los diseñadores de frameworks. La finalidad de las anotaciones es sencilla: permitir al programador definir metainformación con la que decorar métodos, clases, paquetes, campos y argumentos. Sí, sí, pero, ¿que es esto de la metainformación? ¿Que tiene todo esto que ver con mi JPA? La idea es que el programador puede querer añadir información que pertenece al dominio de la aplicación a un método o clase. Si estamos escribiendo un framework de persistencia, será muy útil definir qué clases son persistentes y que propiedad de la clase usar como clave primaria. Fijaros que en este caso, el del framework, el dominio de negocio es la persistencia. Si usáramos un framework de negocio el dominio de negocio seria otro.

Veamos mas en detalle el ejemplo del framework de persistencia (al fin y a al cabo algunos piensan que con tener la persistencia solucionada la aplicación ya esta hecha al 50%, solo le faltarían las pantallas). En dicho framework necesitamos indicar cuales son las clases que representan conceptos persistentes y que propiedad usar como identificador, ese es nuestro dominio de negocio.

¿Como lo haríamos antes del advenimiento de las anotaciones? Simplemente tendríamos un maravilloso ficherito XML (esa moda moribunda) donde haríamos un mapeo indicando que clases son persistentes y que campo usar de identificador. Sin embargo pronto se vio que este enfoque es bastante frágil y propenso a errores. ¿Que ocurre si cambiamos el nombre de la clase? ¿O del campo? ¿Ese nombre era con mayúsculas o minúsculas? ¿Cometí un error tonto al escribir el nombre? Mantener la consistencia entre las clases y campos y el fichero XML puede ser una tarea compleja si el proyecto tiene un tamaño decente. El problema principal está en que información importante respecto a las clases se mantiene en un fichero distinto del código fuente. Esto genera el problema de sincronizar y mantener la consistencia entre ambos ficheros. Por otro lado una persona que lea la clase no sabrá si es persistente o no, con el consiguiente problema de mantenimiento. No contentos con esto, muchos IDEs no poseen capacidades de refactorización que tengan en cuenta el fichero XML de nuestro framework de persistencia favorito.

Debido a estos problemas se importó la idea de las anotaciones desde la plataforma .NET a JAVA. Ahora el diseñador del framework puede eliminar ese fichero XML tan molesto y definir anotaciones para su dominio de negocio. Supongamos que define las anotaciones @Persistente e @Identificador.  Solo tenemos que anotar nuestro código. Solucionamos el problema de raíz al eliminar el fichero XML. Ademas tenemos junto al código fuente nuestra metainformación de persistencia en forma de anotaciones lo que aumenta la mantenibilidad. El framework ahora en vez de leer el XML, lee dicha información directamente desde la clase. Esta lectura y procesamiento de anotaciones se puede hacer en tiempo de compilación, de carga de clases, o mediante reflexión, dependiendo de como hayamos definido las anotaciones y de la sofisticación de nuestro framework. Las anotaciones definidas para ser procesadas en tiempo de compilación son usadas por IDEs y scripts de compilacion. Las accesibles en runtime por reflexión y en tiempo de carga son útiles usadas sobre todo por frameworks. El código de una supuesta clase persistente quedaría así:

// Declara las instancias de esta clase como persistentes
@Persistente
public  class Person implements Serializable {
// Declara esta propiedad como identificador
 @Identificador
 private Integer id;

 private String name;

 public Integer getId() {
 return id;
 }

 public void setId(Integer id) {
 this.id = id;
 }

 public String getName() {
 return name;
 }

 public void setName(String name) {
 this.name = name;
 }
 }

Hasta aquí todo muy bien, ¿donde está la pega? La pega está en confundir metainformación con información de configuración. La información de configuración es aquella que cambia en función del entorno en el que se ejecuta la aplicación, o bien, no esta bajo nuestro control y puede cambiar en cualquier momento. En función de la maquina donde se ejecute, la base de datos, o el servidor de correo que usemos, la información de configuración puede cambiar, o simplemente el administrador puede decidir en cualquier momento cambiar ese nombre de usuario tan importante. Por eso dicha información se suele depositar en ficheros de configuración, para no tener que recompilar tu código cada vez que vayas a cambiar de entorno.  Hoy en día a nadie se le ocurre poner un usuario y contraseña a fuego en el código, ¿verdad? Tal vez estoy siendo demasiado optimista…

Volvamos a nuestro ejemplo de framework de persistencia para ver como esto nos puede llevar a la perdición. Supongamos que somos unos arquitectos muy listos y decidimos mejorar nuestro framework con una nueva anotación: @Tabla Como estamos a la última sabemos que las anotaciones pueden tener campos para ser parametrizadas. Decidimos pues que @Tabla recibirá el nombre de la tabla en la que se persiste el objeto y que en @Identificador podremos definir el nombre de la columna que contiene la clave primaria. Nuestro código quedaría así:

// Declara las instancias de esta clase como persistentes
// La persistencia sera mediante la tabla PERSONAS
@Persistente
@Tabla(tableId="PERSONAS")
public  class Person implements Serializable {
 // Declara esta propiedad como identificador, mapeado a columna PK
 @Identificador(columnId="PK")
 private Integer id;
 private String name;

 public Integer getId() {
 return id;
 }

 public void setId(Integer id) {
 this.id = id;
 }

 public String getName() {
 return name;
 }

 public void setName(String name) {
 this.name = name;
 }
 }

¿Que chulo verdad? FAIL !!!  Cuando instaleis esto en producción os encontráis con la desagradable sorpresa que por razones de nomenclatura los nombres de tabla son $entorno$_$tabla$ y la columna de la clave primaria siempre es $entorno$_$tabla$_PK ¡ Dios, que hacemos ! ¿Cambiamos el código y recompilamos, generando una versión para cada entorno? No señores, damos marcha atrás en nuestro cambio tan chulo y lo tiramos a la basura. Los nombres de las tablas y columnas de identificación hay que ponerlos en un fichero de configuración que cambia por entorno. Esto nos quita el problema de compilar pero no de reempaquetar para cambiar el fichero. Si queremos tener el mismo desplegable en los tres entornos, y ahorrarnos problemas con MAVEN y la gente de sistemas, lo que hacemos es pedir la URI donde se encuentre el fichero mediante JNDI, abrir la URI y procesar el fichero. Debemos además declarar una referencia JNDI a recurso URI. Cada entorno tiene un fichero distinto configurable por la gente de base de datos y en una URI distinta. Durante el despliegue la gente de sistemas mapea la referencia JNDI al fichero correspondiente al entorno y nosotros no nos damos ni cuenta. Existen otras formas de hacer esto, como por ejemplo jugar con el classpath y las librerías compartidas, pero eso en otro post.

Bien, si alguno leyó mi anterior post, puede invocar el poder de KISS para arrearme en «to la boca». Cierto, si en tu proyecto hay ciertos parámetros externos a la aplicación que nunca van a cambiar puedes usar KISS y ahorrarte el fichero de configuración y poner estos parámetros a fuego en tu código mediante anotaciones. Normalmente esto de que hay parámetros que no cambian no me lo encuentro muy a menudo, ya que mis proyectos se mueven en un entorno con alta tasa de cambio e incertidumbre. Si es tu caso, enhorabuena, pero asegúrate bien antes, no tenga que decirte eso de «te lo dije…». En el ejemplo anterior puede ser que realmente el nombre de las tablas lo decida el desarrollador (mapeo top-down) o simplemente no puedan cambiar por los siglos de los siglos.

El caso del mapeo top-down es interesante. Si el nombre de las tablas se puede decidir por parte del desarrollador JAVA, y no cambia con el entorno, podríamos invocar KISS y eliminar esa anotación @Tabla y el parámetro columnId de @Identificador ¿Como? Usando configuración por convención o nomenclatura. De esta forma el nombre de las tablas se deriva del nombre de las clases. Es un mapeo automático que nos evita la configuración, ya sea en forma de anotación o de fichero.

El confundir metainformación con configuración es tan común que muchos estándares JSR y frameworks lo han cometido. El clamor por eliminar ficheros XML y usar las anotaciones era tal que no se pararon a pensar en lo que hacían, ¿o tal vez sí? Si lo pensáis bien, los JSRs y los frameworks tienen que ser populares si quieren ser usados, y lo que te hace más popular es usar lo que esté más de moda, no lo mejor. El usar anotaciones de forma masiva, al ser una tecnología chula, hizo que esos JSR y frameworks se hicieran populares. Un truco muy hábil. O al menos eso es lo que mi mente me dice a veces cuando me pongo en modo paranoico.

Así que ya lo sabéis, usad las anotaciones, diseñad frameworks que las aprovechen, pero no caigais en la tentación de usarlas de cualquier manera y para cualquier cosa.

Read Full Post »