lunes, 29 de noviembre de 2010

Eden por dentro

Hoy he empezado mi internship en Eden y tengo que deciros que esto es la caña. He conocido a Chris, Todd, Spencer, Juliet y Aimee y son todos muy simpáticos y muy amables. Entre Chris y Aimee me han explicado lo que es Eden y me han pasado su "código de valores" (A ver si mañana os blogueo algo). Sinceramente, es una empresa espectacular. No se muy bien como explicarlo, pero escucharles contar como sienten la empresa y verlos en acción con sus clientes deja bien claro que su máximo interes es hacer que las personas se superen. Es muy inspirador.

Aimee y Steve iban a ser los encargados de darme caña estos primeros días, pero Steve (al que conocí en la Software Craftsmanship y al que todavía debo una cerveza) está enfermo y le ha tocado a Aimee lidiar conmigo :) Lo primero que hemos hecho Aimee y yo ha sido modificar la web de Eden. Supongo que la mayoría ya os habréis dado cuenta del cambio :P El proceso entero ha sido muy sencillo. El código está en github y el deploy se hace con un comando. A prueba de plagelaos :)
Más tarde, Aimee me ha encargado (ha petición de enrique vía email) una tarea algo más compleja. Me ha pedido que realice una implementación de un servidor web que cumpla la rfc2616 :) Además, tendré que hacer una exposición sobre el tema el próximo viernes... Por supuesto, hay que desarrollarlo usando TDD (Con Cucumber y RSpec). Para añadir algo de dificultad al ejercicio, me he propuesto hacerlo en Ruby y utilizando el Vim (bueno, el MacVim, que es algo más amigable) ¿Qué puede salir mal? Pues nada, porque hemos venido a aprender y a mejorar, y eso no se consigue dentro de tu zona de confort. Hay que tirarse a la piscina.
Por si os interesa el código lo estoy dejando en github, aunque estos próximos días os iré contando mis dudas y las soluciones. De momento, hoy he aprendido a lanzar todos los specs de mi proyecto a la vez :P Os cuento como lo he hecho. Me he creado un fichero spec_helper.rb en el que he metido todos los ficheros con specs como require. Después lo único que hago es ruby spec_helper.rb y automagicamente se ejecutan todos los tests. Supongo que habrá alguna forma más sencilla de hacerlo ¿Me la contáis? Tampoco me importaría mirar un poco como funciona autotest...

No quería terminar sin agradeceros a todos los ánimos que me estáis dando :D ¡Muchas gracias!

Por cierto, creo que en Madrid ha nevado hoy ¿no? Aquí ha salido el sol por la mañana :) La vida puede ser maravillosa, que decía aquel.

Saludos del "Lucky Bastard" :P

PD: Me dejo muchas cosas en el tintero (Todd explicándome que si tengo algún problema no dude en hablar con él, Spencer recogiéndome en el B&B para llevarme a Eden, el bollo que me ha comprado Juliet, las cañas que nos hemos tomado al salir con los chicos de la empresa cliente a la que están ayudando de la que no recuerdo el nombre ahora, etc). Todo genial.

domingo, 28 de noviembre de 2010

Un plagelao en Winchester

¡Sí, ya estoy en Winchester! De momento (no podía ser de otra forma) todo está siendo espectacular.

Para empezar, Enrique Comba me ha ido a recoger a la estación y me ha acompañado a lo que va a ser mi casa durante este mes, Flowerdrews. Es el B&B que me buscó Juliet Arnott y es increíble (además de calentito). Siento no tener cámara de fotos (sí, soy lamentable), pero os lo recomiendo 100% a todos los que vengáis a Winchester. Es un sitio bastante tranquilo, las habitaciones son enormes y la pareja que lo lleva es super amable :)

Después de dejar la maleta y la mochila en la habitación, Enrique me ha llevado a las oficinas de Eden Development. "Yo... He visto cosas que vosotros no creeriais" :P Las oficinas reflejan todo lo que Enrique nos ha contado tanto en el aos2010 como en la lista de agile-spain. Hay restos de inceptions, story boards, libros, teclados Dvorak, sillas con nombres de bólidos, un globo-clon y muchos Macs ("ordenadores de verdad" los llama Enrique). Un pasote :) Sin embargo, lo que más me ha llamado la antención es la cantidad de espacio "libre" que tienen. De hecho, Enrique me ha contado que ellos no tienen un sitio fijo en el que trabajar. Cada uno trabaja donde le da la gana (o donde haya elegido su pareja, claro). Estoy deseando ir mañana para ver el taller a pleno rendimiento :) Va a ser una pasada.

Tras la visita a las oficinas de Eden, nos hemos ido de ruta turística por Winchester. Hemos visto al Rey Arturo, el mercado de Navidad, el centro de la ciudad, la catedral (testimonio gráfico incluido), etc, aunque lo mejor ha sido la charla durante el recorrido, saltando del software a la fotografía, pasando por la comida y, como no, por Eden Madrid :)

Siento que la entrada sea tan cortita, pero estoy baldado y mañana va a ser un día duro. De hecho, una de las cosas que me ha dicho Enrique es que esta primera semana las voy a pasar canutas, así que me voy a dormir :) ¡Mañana más!

miércoles, 24 de noviembre de 2010

Más sobre S.O.L.I.D.

En el último post os intenté convencer de que habíamos conseguido no violar el principio de inversión de dependencias con nuestra clase Banco. Si no lo recordáis, nos quedó algo como esto:



José Luis Barrera me sugirió en los comentarios que utilizáramos una clase Credenciales que agrupara tanto el nombre del usuario como el Pin. Con esa nueva abstracción, el código de Banco queda aún más claro:



Guay :D

Ahora bien, ¿qué ocurre cuando la validación de las Credenciales falla? Tal y como tenemos ahora mismo nuestra implementación, OperacionesBancarias lanzaría una excepción por cada tipo de error que se produzca al validar el usuario. Por ejemplo, si lo que falla es que las Credenciales son incorrectas se produce una excepción CredencialesIncorrectas. Si lo que sucede es que la validación de las Credenciales ha sido fallida más de tres veces, la excepción que se lanza es una AccesoInvalidadoPorMultiplesReintentosFallidos. Si lo que se produce es un error en el acceso al banco real, se lanzará un BancoInaccesible.
Veamos como implementaríamos un cliente de Banco (un Cajero) que se preocupe del resultado de la validación:



Pues no parece que sea muy legible... No se vosotros, pero yo estoy bastante acostumbrado a este tipo de código y tengo que decir ¡basta ya!
Las excepciones que captura Cajero no son parte de la abstracción de Banco, son detalles de bajo nivel que se encuentran en OperacionesBancariasBancoManolito, con lo que estamos volviendo a violar el principio de inversión de dependencias. Además, estamos controlando el flujo del programa mediante excepciones. ¡Que desastre!

Las excepciones deberían ser para casos excepcionales
Como bien nos contó (recordó) Enrique Comba en el curso de T.D.D., las excepciones deben ser excepcionales. No tiene sentido usarlas para controlar el flujo porque, en ese caso, dejan de ser excepcionales. Esto que parece tan trivial es una de las cosas que más nos cuesta cuando nos ponemos a programar.
Con esto en mente, volvamos a nuestro ejemplo, ¿Es excepcional que unas Credenciales sean incorrectas? ¿Es excepcional que un Banco tenga que anular una tarjeta porque el usuario se ha equivocado n veces al intentar usarla? De nuestro ejemplo, el único caso "excepcional" puede ser que el banco real no esté accesible pero ¿de verdad es tan raro que haya un corte de comunicaciones? Para mi, ninguno de estos casos es merecedor de una excepción, así que vamos a intentar arreglarlo. Lo primero que vamos a hacer es que Cajero no dependa de los detalles de OperacionesBancariasBancoManolito (y si de paso evitamos controlar el flujo con excepciones, mejor que mejor). Para ello, vamos a pasarle al Banco la responsabilidad de avisar al Cajero cuando suceda un evento de validación (correcta, incorrecta, invalida, sin conexión). Refatorizamos nuestro Banco para que quede como sigue:



y nuestro Cajero ahora queda mucho más limpio:



Aunque nuestra clase Cajero ha quedado mucho más clara, hemos pasado el problema de las excepciones a la clase Banco. Además, estamos violando el principio de segregación de interfaces (I). Vayamos paso a paso.

Segregación de interfaces

Clients should not be forced to depend upon interfaces that they do not use.

Los clientes no deben verse forzados a depender de interfaces que no usan.

Para cumplir este principio, nuestra clase Cajero debe implementar un interfaz para manejar los eventos de validación, que es lo único que la clase Banco necesita conocer de Cajero:



Y nuestra clase Banco dejaría de depender de Cajero para depender de dicho interfaz:



Ahora que nuestra clase Cajero ya cumple el principio de segregación de interfaces, arreglemos Banco.
La solución que se me ha ocurrido es que sea la abstracción Token la que nos de la información que actualmente nos dan las excepciones:



Ahora el flujo ya no es guiado por excepciones pero, lo que me parece más importante aún, es que nuestro código ahora es más sencillo de extender. Antes necesitábamos ir a un javadoc (o similar) para leer que tipo de excepciones eran necesarias para que Banco funcionara, ahora basta con implementar Token.

Por último, tengo que decir que no me gustan las estructuras if-elseif-elseif-else, pero para este caso en particular no me parece tan horrible. Si los motivos por los que Token puede no ser válido fueran más o pudieran cambiar más a menudo me pensaría una solución con suscriptores similar a la que hemos utilizado con el Cajero. Si os apetece hacerlo os lo dejo como ejercicio :P

Perdonad que me haya quedado una entrada tan larga y atolondrada. Espero que al menos se entienda lo que he intentado expresar :D ¡Nos vemos en la siguiente!

Nota: No haría estas refactorizaciones que he hecho aquí si no tuviera una buena base de pruebas contra las que probar cada pasito.

jueves, 18 de noviembre de 2010

Violando la D de S.O.L.I.D

A principios de semana tuve la suerte de asistir al curso de TDD que impartió Enrique Comba en Madrid. Me lo pasé genial pero me fui aún más convencido de que programar es muy difícil.
Aunque el temario del curso fue bastante amplio, yo sólo voy a centrarme en los principios S.O.L.I.D. Si queréis saber más sobre lo que hicimos allí, Jesús Jiménez ha escrito este post explicándolo.

El primer día del curso, Enrique nos dividió en 5 grupos y nos asignó la exposición de un principio S.O.L.I.D. a cada equipo. A nosotros (Amalia Hernandez, Jesús Jiménez, Leo Antolí y yo) nos tocó explicar la D.

Inversión de Dependencias (D)

High level modules should not depend upon low level modules. Both should depend upon abstractions
Abstractions should not depend upon details. Details should depend upon abstractions

Los módulos de alto nivel no deberían depender de módulos de bajo nivel. Ambos deberían depender de abstracciones
Las abstraccciones no deberían depender de los detalles. Los detalles deberían depender de las abstracciones

Cuéntamelo con código
El segundo día lo dedicamos a crear el software que controla un cajero automático (haciendo T.D.D., claro). El código que creó nuestro equipo (los mismos cuatro que el día anterior) lo tenéis completo aquí, pero yo me voy a centrar sólo en nuestra implementación de la clase Banco:



Lo que hace la clase Banco es realizar una petición de validación mediante el Conector a una url. Dicha validación nos devuelve un json a partir del cual se puede crear el token de seguridad con el que se realizarán las siguientes operaciones del usuario validado.

¿Habremos sido capaces de respetar el principio que nos tocó explicar el día anterior?

Los módulos de alto nivel (Banco) no deben depender de módulos de bajo nivel(Implementaciones de Conector y GeneradorToken), ambos deben depender de abstracciones. Nuestro Banco depende de la abstracción Conector y de la abstracción GeneradorToken, pero no "conoce" que implementación de cada abstracción está usando (Ambas se le inyectan en el constructor). Parece que esta parte es correcta.

Las abstracciones (Banco) no deben depender de detalles. Los detalles deben depender de abstracciones. En esta parte es donde hemos metido la pata. Si Banco no debe depender de detalles ¿Qué pinta la construcción de la url contra la que debe operar el Conector? ¿Por qué el Banco conoce que el Conector devuelve json?

Pensando en esto se me ocurre el siguiente refactor de Banco:



Nuestro módulo de alto nivel depende ahora de una abstracción más general, dejándole a los módulos de bajo nivel (Las implementaciones de OperacionesBancarias) todo lo que tiene que ver con la infraestructura (tipo de comunicación, transformación de la respuesta, etc). Pero, ¿no es el token un detalle de bajo nivel? Si la respuesta es afirmativa deberíamos eliminarlo de Banco y OperacionesBancarias devolvería directamente la Cuenta, haciendo que nuestra clase Banco fuera redundante. Sin embargo, yo (que soy el que está programando :P ) creo que cualquier autenticación bancaria me va a devolver un token (hablo desde la ignorancia, pero suena bien) con lo que deja de ser un detalle para formar parte de la abstracción. Eso sí, no estaría mal que fuera una clase Token en lugar de un String, que no todos los tokens tienen porque ser iguales. La clase Banco que no viola el principio de inversión de dependencias quedaría así:



Conclusiones
Yo ya conocía los principios S.O.L.I.D. y se que mis compañeros también (aunque de este código tenemos la culpa Leo y yo :D ). Nos habíamos preocupado de leerlos y de intentar entenderlos mucho antes de dar este curso. Entonces, ¿por qué no fuimos capaces de recordar la dichosa D. incluso habiendo tenido que explicarla el día anterior? Yo pienso que es porque no lo tenemos interiorizado. Hace falta mucha práctica y mucha experiencia trabajando con los principios S.O.L.I.D. en la cabeza para que no se te olviden mientras programas. Por eso considero importante practicar T.D.D. con ejemplos sencillos, porque lo importante no es resolver el problema, lo importante es el proceso mental con el que resuelves el problema.


Criticadme, por favor
Lo que os he contado en este artículo es como entiendo yo el principio de inversión de dependencias. ¿Coincide con lo que entendéis vosotros? Si no es así, ¿en que me he equivocado?

lunes, 25 de octubre de 2010

Pair Programming Cara a Cara

Hace poco he empezado a tomarme más en serio mi relación con la Software Craftsmanship.
He decidido andar "El Largo Camino" (The Long Road).

Mi largo camino
En el Coderetreat que organizó Agilismo.es (patrocinado por Autentia y Eden Development ¡Gracias!) tuve la suerte de desvirtualizar a Enrique Comba el cual me regaló una copia del "Apprenticeship Patterns, Guidance for the Aspiring Software Craftsman". Si os interesa la Software Craftsmanship tenéis que leer este libro. Entre otras muchas cosas, algo que deja claro es lo importante que es relacionarse con otros, aprender de otros y enseñar a otros.

A su vez, hace poco que un grupo de españoles (vale, también había un argentino) fuimos a la conferencia SC 2010 en Bletchley Park. El mensaje que Jason Gorman quiso transmitirnos allí fue:

Enseñad vuestro código, enseñad lo que hacéis, difundid la palabra

Así pues, he decidido que, en esta parte del camino, voy a intentar relacionarme con la gente para enseñarles lo que hago y aprender lo que ellos hacen. Voy a compartir con otros mis experiencias.

Compartir con otros
Tras volver de Londres escribí un twitt ofreciendome a programar con gente con una sola condición, tenía que ser cara a cara. A aquel twitt contestarón varios apasionados del software. Aún tengo pendiente quedar con varios de ellos (no os he olvidado :P), pero ya he tenido mis dos primeras experiencias.

Apasionados
Mi primera vez (sé como suena) fue con @jjballano. Nos reunimos para hacer la kata "StringCalculator" en Java. No llegamos a acabarla (¿es una kata muy larga o solo me lo parece a mi?) pero sí que avanzamos bastante en la solución. Creo que, aunque empezamos haciendo ping-pong programming, no dejé participar demasiado a Jesús (no se como lo vio él, pero hice un refactor demasiado largo). Habrá que repetir y "arreglar" eso.

La segunda vez hice un trío (sé como sigue sonando) con @GermanDZ y @reemplazable :P Nos decantamos por esta kata en Ruby. Tras intentar instalar RSpec (sin éxito), acabamos usando Test::Unit y terminando la kata. Aprendimos un poquito de Ruby, @GermanDZ nos enseñó como afronta él las refactorizaciones y @reemplazable hizo una linea de código que nos dejó locos :). Creo que fuimos un poco rápido y 13'' no es lo mejor para tres personas, pero estuvo muy bien. Después nos tomamos las debidas cañas, que molaron igual o más :P

Futuro
Lo próximo que quiero hacer es grabar una de estas sesiones y subirla al internet para que la podáis ver todos.

Si os apetece programar una tarde conmigo no tenéis más que avisarme. Eso sí, daos prisa porque el próximo 30 de noviembre me marcho a Eden Development. Me han ofrecido hacer un internship y, si todo va bien, convertirlo en un apprenticeship :D Ya os iré contando.

Estoy muy contento y féliz :)

lunes, 10 de mayo de 2010

Principios ágiles #6

Hace muuuucho tiempo comencé una serie de post sobre los principios ágiles que hay detrás del manifiesto ágil. No se por qué, dejé de escribir en el blog y la serie se interrumpió. Hoy, a lo Fronkonstoin, voy a devolver la serie a la vida hablando del sexto de ellos (esperemos que dure):

The most efficient and effective method of conveying information to and within a development team is face-to-face conversation.
El método más eficiente y efectivo de comunicar la información a un equipo de desarrollo y entre los miembros del mismo es la conversación cara a cara.

Comunicar información
¿Por qué hay gente que oculta información, que no comparte? Quizás para hacerse indispensables (como bien dice David Bonilla en su entrada sobre cajas negras). Que no os engañen, no lo son y no lo serán. Lo único que van a conseguir es aislarse de sus colegas de profesión y perderse todas las cosas buenas que hay fuera de su cubículo. Van a quedarse obsoletos.

Como decía Newton (aunque la wikipedia dice que fue Chartres):

Si he visto más lejos es porque estoy sentado sobre los hombros de gigantes

Si es bueno para Newton (vale, Chartres. Creo que se nota que soy físico) es bueno para ti.

Hay que salir, enriquecerse. Hay que aprender a ser humilde, a compartir tus conocimientos. Hay que enseñar lo que sabes y aprender lo que no sabes. Para todo esto es necesario comunicarse. No te conviertas en una caja negra.

A un equipo de desarrollo
Como he dicho ya muchas veces en anteriores posts, es importante que el cliente esté en contacto continuo con el equipo. Que sea capaz de comunicar sus objetivos y preferencias es una parte imprescindible de dicho contacto. Esto implica un nivel de compromiso por parte del cliente en el proyecto muy alto, siendo éste uno de los problemas más comunes en los equipos ágiles (al menos en los que yo conozco). Veamos un dialogo tipo:

- Hola, ¿vosotros sois ágiles?
- ¡Sí!
- ¿Cómo habéis conseguido involucrar al cliente en el ciclo de desarrollo?
- Respuesta 1: A no, eso no lo hemos conseguido.
- Respuesta 2: Nuestro cliente es interno.

Mi experiencia personal es del segundo tipo, así que tengo suerte :P Sinceramente, no se cómo resolver el primer caso :( Lo que sí que tengo claro es que, si no consigues que tu cliente se comprometa en el proyecto vas a pasarlas canutas...

Entre un equipo de desarrollo
Está claro que un equipo de desarrollo, si es sano ,debe estar en continua comunicación. Cuando se trabaja en intervalos de tiempo cortos es necesario que todo el equipo esté sincronizado de forma que se evite el trabajo duplicado. Igualmente, es muy importante que los miembros del equipo se encuentren comodos entre si, de forma que no resulte extraño que alguien pregunte cuando no sabe algo (No hay preguntas tontas ni respuestas estupidas, ya sabéis). Básicamente, es necesario que los miembros del equipo creen relaciones de confianza que ayuden el desarrollo de su trabajo (Todos trabajamos mejor con amigos alrededor ¿no? Huy, me ha salido muy piruleta esto último...).

Conversación cara a cara
Lo más eficiente no es ni usar el teléfono, ni el e-mail, ni el wave, ni el twitter, ni el skype... lo más eficiente (y por tanto lo deseable) es la comunicación cara a cara.

Pensad en la cantidad de herramientas que propone el agilismo a los equipos para que mejoren su comunicación. Desde el ¡Sienta al equipo junto! de Henrik kniberg a las reuniones diarias de Scrum sin olvidarme de algunas de las prácticas XP como la programación en parejas. Todas ellas se basan en la comunicación cara a cara, lo que debe dar una idea de su importancia.

Conclusiones
El sexto principio ágil:

  • Implica un alto nivel de compromiso en el proyecto por parte del cliente
  • Necesita que se den relaciones de confianza entre los miembros del equipo (incluido el cliente)
  • Señala la importancia de la relación directa entre las personas


Foto de "portada": Galería de Fernando en Picasa, bajo licencia Creative Commons.

martes, 2 de febrero de 2010

Principios Ágiles #5

Siguiendo con la temática de los principios ágiles, hoy voy a hablar del quinto de ellos:

Build projects around motivated individuals. Give them the environment and support they need, and trust them to get the job done.

Construye proyectos con profesionales motivados. Dales el entorno y soporte que necesitan, y confia en ellos para que realicen el trabajo.

Profesionales motivados
Cuando una persona encuentra un nuevo trabajo su motivación inicial es bastante alta. Si tiene experiencia previa probablemente haya conseguido un trabajo que le guste con un sueldo acorde a dicha experiencia. Estará contento y querrá demostrar que vale lo que le van a pagar. Si es un junior sin experiencia querrá aprender y prosperar en su carrera profesional. ¿Qué lleva a cualquiera de estas dos personas a desmotivarse? Pues multitud de causas. Falta de dirección (visión de empresa, visión de producto, abandono por parte de la gerencia...), mala cultura empresarial (mala relación entre compañeros, infraestructura deficiente, falta apoyo al aprendizaje), etc. Imagino que todos hemos pasado por algo así en algún momento, por desgracia.
Una vez que una persona pierde la motivación es muy complicado volver a motivarla, por lo que hay que esforzarse en evitar que ocurra.
¿Cómo se puede evitar la desmotivación?
Dan Pink lo explica muy bien en esta presentación (Si aún no la habéis visto ya estáis tardando :P)
Os escribo las conclusiones para los más vagos (aunque ya os digo que mola mogollón). Básicamente cuenta que, una vez resuelto el tema salarial (está claro que es un factor importante, pero no el único) los factores que ayudan a mantener la motivación son los siguientes:

  • Autonomía. Muy en sintonía con la auto-organización de los equipos ágiles ;) Hay que confiar en que el trabajador es capaz de hacer su trabajo por si mismo.
  • Maestría. Para los agilistas significa buscar la excelencia técnica (Sea lo que sea eso, que ya lo veremos en futuras entradas)
  • Propósito. Contribuir a algo importante. En el caso de la agilidad sería equivalente a contribuir en la mejora del negocio del cliente. Aportar valor y tal :)

Estos tres factores ayudan a mantener la motivación de un profesional (no solo los profesionales técnicos, cualquier tipo de profesional) ya que crea un entorno en el que las personas son importantes y valiosas (Ya sabéis, personas sobre procesos...).

Crear un entorno y dar el soporte necesario
Tal y como hemos visto arriba, la cultura empresarial es muy importante a la hora de mantener la motivación.
Es necesario que la empresa proporcione un ambiente que favorezca el aprendizaje, que ayude a crecer profesionalmente a sus trabajadores, que confíe en ellos para realizar su trabajo, que les proporcione una infraestructura adecuada a sus necesidades, etc. Es decir, que se dedique a eliminar impedimentos externos del día a día para que los únicos problemas que se encuentren sus trabajadores sean los propios de su trabajo (Eliminar burocracia inútil, métricas absurdas, controles exhaustivos, etc).

Confianza
Todo lo anterior se basa en la confianza. Está claro que un buen profesional sabe hacer su trabajo. No necesita un jefe todo el día detrás suya, interrumpiéndole cada 10 minutos para preguntarle qué tal lo lleva. Ese micro-control, además de desmotivar, reduce la productividad.
Sin embargo, hay que tener claro que no todo depende de área de gestión, el empleado debe responder. Como dijo el Tío Ben :

Un gran poder conlleva una gran responsabilidad

Si queremos que nuestro trabajo mejore, que se nos trate como a verdaderos profesionales y que se confíe en nosotros, debemos responder con autentica profesionalidad. Si nuestra empresa fomenta el aprendizaje debemos aprovecharlo y mejorar. Si nuestra empresa nos permite autonomía debemos comprometernos. No podemos desaprovechar las (¿pocas?) oportunidades que se nos ofrecen.

Conclusiones
El quinto principio ágil:

  • Busca fomentar la confianza
  • Advierte que lo importante son las personas
  • Pide que se eliminen los impedimentos externos
  • Implica responsabilidad y profesionalidad


NOTA: Si os interesa más el tema de la motivación de un equipo os recomiendo el libro Peopleware. Yo aún no lo he podido leer, pero José Manuel Beas lo recomendó en la reunión que tuvimos sobre principios ágiles al hablar sobre este principio. El libro se lo dejó a Alfredo Casado, que nos ha ido contando algunas de las cosillas que ha ido leyendo. La verdad es que tiene muy buena pinta :)

Foto de "portada": Galería de Fernando en Picasa, bajo licencia Creative Commons.