miércoles, 27 de octubre de 2010

Liderazgo (I)

Hace tiempo, más tiempo del que me gustaría, en uno de mis primeros trabajos, se me acercó mi jefe de ese momento y sin más preambulo que una aclaración de garganta, en un tono seco y muy cortante me informó:

"La empresa necesita destruir unos papeles. Te vas mañana por la mañana a una planta de desechos en Loma-del-Ortis."
Y se dio la vuelta para Irse. Mi respuesta fue casi automática, visceral e inmediata:
"No", le dije.
La espalda se detuvo, y juro que percibí como se contracturaba todo antes de volverse con cara de pocos, poquísimos amigos:
"Como? que no vas a ir?"
"No, porque no me pagan para eso, soy programador."

La discusión que siguió fue bastante fea, con acusaciones de "Sos un principista", "no estas alineado con la empresa", etc.

La discusión fue doblemente fea porque podría haberse evitado totalmente. Que les parece que hubieran contestado si lo planteaba de la siguiente manera:

"La empresa tiene que mandar a destruir unos papeles. El que quiera ir tiene que levantarse un poco mas temprano, lo pasan a buscar en remise, el desayuno lo paga la empresa y a las 15 horas esta libre y se puede tomar el resto del dia libre. Quien quiere ir?" Porque realmente esas eran las condiciones.

Hace poco Martin Alaimo preguntó en la lista de foros-agiles que rol de Scrum era mejor para "reciclar" a un PM de la escuela PMI-stica, si era mejor que se transformara en un Product Owner (PO) o en un Scrum Master (SM).

Mas allá de la parte metodológica de la discusión que siguió: que en general se los asocia mas como Scrum Master, que los Analistas Funcional hacen mejor de PO, incluso mejor que los propios clientes , que depende del PM, que mejor continua fuera de Scrum llenando planillas o projects, etc., mas allá de todo esto, decia, de manera subyacente se estaba discutiendo el tema del Liderazgo y de que características deben tener un buen líder para ser efectivo (tanto si se hablaba del rol como PO, SM u otro).

Pueden ver la discusion original aqui, pero para resumir hubo excelentes aportes de Ingrid Astiz, Jose Manuel Beas, Pablo Rodriguez Facal y varios otros que fueron desgranando características (a veces por la negativa) entre las que rescato:

  • Un líder debe poner de costado su "propio ego"
  • Debe tener humildad y poner lo menos posible de su propio ruido
  • Aportar herramientas practicas y dejar que el equipo descubra su potencial.
  • Renunciar a la ilusión de importancia personal
  • No ser burócrata
  • Sentirse incomodo con forma de Gestionar de "Comando y Control"
  • Ayudar al equipo a triunfar
  • Escuchar a la gente
  • No adjudicarse el merito de los demás
  • No crear conflictos
  • No manipular
  • No caer en la inercia y tratar siempre de mejorar
  • No caer en la ilusión del control
  • No culpar al equipo por los fracasos
  • No tiene que estar encima de todos
  • debe confiar en las personas del equipo

¿Que les parece eh?! Pavada de listita!! Interesante para chequear a nuestro alrededor, verdad?

jueves, 21 de octubre de 2010

El miedo apropiado

Greg Poppovich es el entrador de los San Antonio Spurs (el equipo donde juega Ginóbili). Es un gran entrenador y ganó 4 títulos de la NBA. ¿Por qué lo mencionamos en este blog (además de para que nos lleguen todas esas búsquedas de Google)? Porque tiene una enfoque muy interesante sobre algo con lo que tenemos que tratar a menudo los programadores: el miedo.

A primera vista, no parece que el miedo tenga mucho que ver con lo que los programadores hacemos todos los días. Después de todo es poco probable que nuestras acciones causen daños graves a nadie. Sin embargo, todos los que hemos estado algún tiempo en esta profesión sabemos que es algo que nos acompaña todos los días. En uno de mis primeros trabajos, el miedo había llegado tan lejos que muchas de las personas en el proyecto se habían vuelto superticiosas, y no había manera de que alguien te aceptara que le alcanzaras un salero en la mano (y ni hablar de hacer una implementación un martes 13).

En el desarrollo de software, el miedo suele ser un enemigo, porque funciona como paralizante. Nos lleva a recurrir a parches en vez de realizar cambios que sabemos que son necesarios pero que nos obligarían a tocar partes del programa que nos aterrorizan. O nos hace seguir trabajando con tecnologías obsoletas (el típico "nadie fue despedido por elegir IBM").

Sin embargo, el miedo también es nuestro aliado. Cuando son las 5 de la mañana de una puesta en producción y finalmente parece que lo logramos y hacemos una última prueba antes de irnos a casa, es el miedo el que nos hace sacar fuerzas para no irnos ya a dormir. Cuando escribimos casi tantas líneas de tests de unidad cómo de código de producción también es el miedo a esas sesiones interminables de debugging el que nos ayuda a tomar ese camino, que en apariencia es más largo.

Entonces, ¿Cual es la actitud correcta frente al miedo? En mi opinión, la actitud de Poppovich: cuando un equipo gana seguido, tiende a perder perspectiva y a no tenerle miedo a los rivales. Esta actitud genera autocomplacencia y más tarde o más temprano provoca errores que causa que se pierdan partidos que se podrían haber ganado. Pero tenerle miedo a los rivales hace que uno juegue sin confianza y no se anime a tomar riesgos y que termine también perdiendo partidos que podría haber ganado. Por lo tanto, el objetivo es tener lo que Poppovich llama "Appropiate fear": suficiente miedo como para no hacer macanas por sobrar la situación, pero no suficiente como para que nos paralice.

Llegar a esta actitud lleva años tanto en basket como en desarrollo de software, pero realmente creemos que es la marca del profesional maduro de cualquiera de las dos disciplinas.

martes, 12 de octubre de 2010

Largá el twitter!

Probablemente el consejo de usabilidad más conocido por todos los programadores es el no construir menúes con más de 7 +- 2 opciones. Seguramente nuestros lectores recuerdan el motivo de este criterio: los seres humanos (y generalmente nuestros usuarios lo son) tenemos problemas en mantener en nuestra memoria de corto plazo más de esa cantidad de elementos a la vez.

¿Qué es la memoria de corto plazo? Para explicarlo en términos nerds (y muy simplificados), es una suerte de cache donde nuestro cerebro guarda cosas que podemos acceder en forma extremadamente rápida. Cuando todo lo que necesitamos para realizar una tarea está en esta cache, el desarrollo "fluye" y se producen esos momentos en que todas las ideas que tenemos son fácilmente plasmadas en nuestro código. Es en estos momentos cuando una hora de trabajo nos rinde más que ocho horas de trabajo normal. Este fenómeno es lo que en inglés se conoce como "flow" o estar "en la zona".

Este estado de concentración total es dificil de alcanzar y es muy frágil. Cualquier interrupción hace que nuevas cosas ocupen nuestra cache y cuando queremos volver a nuestra tarea el cerebro empieza a "paginar", buscando los pedazos de información que necesita para continuar. Si estas interrupciones se producen muy a menudo, trabajamos todo el tiempo de una manera muy inferior a nuestro verdadero potencial y todas las tareas nos llevan mucho más tiempo del que deberían.

Entre las interrupciones que sufrimos normalmente, las mas comunes son las interrupciones producidas por nuestros compañeros de trabajo o, peor aún, por nuestros jefes. Estas son interrupciones dificiles de evitar. Una manera es llegar muy temprano o quedarse más tarde en el trabajo, de manera de tener unas horas de productividad por día. Otra manera es ponerse de acuerdo entre compañeros y hacer los pedidos de ayuda de una manera no intrusiva, de forma tal que la persona a la que vamos a interrumpir pueda manejar el momento en que responde a nuestro pedido (por ejemplo por mail). A riesgo de quedar como un antisocial, también es posible enchufarse los auriculares y poner "Cowboys from Hell" a todo volumen.

Otras interrupciones son mucho más fáciles de solucionar, aunque requieren más fuerza de voluntad. Me refiero a las interrupciones causadas por messengers, redes sociales, mails, etc. A menudo he visto trabajar a programadores a la vez que chatean con 3 o 4 personas y generalmente estos programadores producían código de baja calidad, con millones de bugs y mucho más lentamente que los programadores que trabajaban más concentrados. Esto no quiere decir que se deban prohibir estas herramientas (y mucho menos que los programadores deban trabajar sin conexión a internet, como he visto en algunas empresas). Quiere decir que es importante separar el tiempo en que se está programando del tiempo en que se está chateando, y que aunque parezca antiintuitivo, un programador que dedica 6 horas de su tiempo a programar y 2 a chatear va a ser mucho más productivo que si dedicara sus 8 horas a programar a la vez que chatea.

Ultimamente estoy utilizando una forma de trabajo basada en la técnica Pomodoro (aunque no siguiéndola al pie de la letra ya que esta tiene otras cosas interesantes, que espero poner en práctica en algún momento). Básicamente divido mi tiempo de trabajo en mini-sprints de 24 minutos. Durante esos mini-sprints desactivo los messengers, las notificaciones de mails y básicamente todo lo que me puede llegar a interrumpir. Trabajo totalmente concentrado durante esos 24 minutos y cuando termino me tomo unos 5 minutos para descansar. Antes de arrancar el siguiente sprint, verifico si tengo mails que contestar o si alguien intento chatear conmigo. Cada tres o cuatro sprints, me tomo un descanso un poco más largo.

De esta manera, puedo mantener períodos intensos de concentración y a la vez solo estoy incomunicado por a lo sumo 24 minutos por vez. Es interesante que en las primeras épocas en que utilicé está técnica, terminaba el día muy cansado, por la falta de costumbre de trabajar realmente a full tanto tiempo.

Nuevamente, estas ideas no apuntan a que nos comportemos como robots ni a que seamos antisociales, trabajando todo el tiempo totalmente concentrados y sin comunicación con el resto. El ambiente laboral es algo muy importante y las charlas y los chistes alrededor de la cafetera ayudan a formar ese ambiente laboral. También son muy importantes las reuniones de equipo como el Daiyly Meeting, de Scrum. Lo que buscamos es maneras de hacer que el tiempo que dedicamos a programar sea mucho productivo solo dedicándose a ..... Programar!.

miércoles, 6 de octubre de 2010

Code Smell - Codigo Duplicado

Queridos Chimpances entrenados, Recuerdan lo que eran los Code Smells?

Bien, si tuvieramos que entregar el Oscar a los Code Smells, el número uno, el primer premio se lo lleva sin dudarlo el código duplicado.

Codigo duplicado implica tener la lógica del sistema duplicada en dos o mas lados, en la misma o distintas clases, incluso en distintas capas.

Porque esto es malo?

El primer problema es que cuando tengamos que modificar el código duplicado (y SI,antes de que pregunten les digo: Vamos a tener que modificarlo con 100% de seguridad) es muy probable que nos olvidemos de cambiar alguna ocurrencia de la duplicación, introduciendo bugs.
En segundo lugar estamos salteando una relación de ese código con alguna de las clases. Es decir, a alguna clase realmente le corresponde ese comportamiento que está duplicado y en el resto de los lugares de la duplicación no estamos honrando está relación que mas pronto que temprano nos traerá problemas.
Es fundamentalmente en este sentido en que es un Code Smells de nuestro diseño. Algo malo esta pasando, falta un método y ese método debe ir en alguna clase lo cual causará un rediseño de nuestro sistema.
En tercer lugar el código duplicado produce que el código sea más dificil de leer y de entender.

Además, el código duplicado tiende a ser modificado de maneras ligeramente distintas en cada una de las copias, con lo que suele pasar que después de un tiempo ya no es trivial decir si dos fragmentos de código que originalmente eran duplicados siguen haciendo lo mismo o no.

En sintesis, el problema fundamental de tener la lógica duplicada es que hace al sistema más dificil de mantener, y ya sabemos que la mantenibilidad es la propiedad numero #1 que debemos procurar para nuestro codigo.

Ahora bien, la lógica duplicada a menudo se presenta en formas mucho más sutiles que una duplicacion literal de codigo, si bien hemos visto más de un ejemplo de estos.

Podemos encontrar los siguientes tipos (principales) de duplicacion de código:

1 - Duplicacion simple: Es la forma más común de duplicacion. Sucede cuando se tiene la misma expresión (identica o diferentes en variables) en dos métodos de la misma clase. La solución es aplicar el refactoring "Extract Method" extrayendo el código duplicado en un método privado y llamando desde ambos lugares de la duplicación al nuevo método.

2 - Duplicación en clases relacionadas : Es cuando se encuentra la misma expresión en dos o más subclases de una misma jerarquia de Clases. Es una duplicación bastante común también ya que provienen de comportamientos comunes de clases hermanas hijas de una misma Clase padre. La forma de solucionarlo es extraer el codigo duplicado en ambas subclases con "Extract Method" y luego si aplica a todas las subclases subirlo a la clase padre, si no aplica es una indicación de que hay un problema de diseño con la jerarquía de clases. A veces hay parte de una logica duplicada y otra parte no, en ese caso se puede convertir el método en un "Template Method" en la clase padre, abstracto y luego implementar la parte que es diferente en ambas subclases.

3 - Duplicación en clases no relacionadas : Como el titulo lo indica, es tener duplicación en dos métodos de dos clases A y B no relacionadas por herencia ni interfases. En este caso se debe considerar extraer el comportamiento duplicado en la clase A y generar una nueva clase C que contenga este codigo (refactoring "Extract Class") y luego reemplazar el código duplicado en la segunda clase B por una invocación a la nueva C. Otra posibilidad es que la lógica duplicada realmente pertenezca a una de las dos clases, y la otra debe invocar a la clase a la que pertenece el codigo. Una tercera posibilidad es que pertenezca a otra clase ya existente. Aplicando la Ley de Demeter, el Single Responsability Principle y el sentido común tenemos que encontrar el lugar adonde esta lógica pertenece y removerla de todo otro lugar.

4 - Duplicación en distintos lenguajes : Por ejemplo, validaciones que tenemos que hacer tanto en la GUI (por ejemplo en Javascript) y en el backend (por ejemplo en Fortran... :)). Este es un tipo de validación dificil de evitar. Una manera posible es escribir el código para uno de los lenguajes y generar el código del otro automáticamente a partir de este.

Para terminar les dejamos una regla práctica para aplicar cuando estamos ante una duplicación de código.

La regla del tres (Don Roberts)

La primera vez que uno escribe una lógica la escribe y listo. La segunda vez que uno hace algo similar debe fruncir el ceño, tomar nota y dejar la duplicacion de cualquier manera. La tercera vez que aparece la duplicación, bang!, uno debe eliminarla, a través de la refactorización.

Entonces, recuerden, Una de las Buenas Practicas de programación que más recomendamos es buscar todo Code Smell que encuentren en el codigo y removerlo a través de la refactorización.
Y si pensamos que el código duplicado es el origen de muchos males (Duplication is evil) y uno de los Code Smell más comunes, aprender a buscar, detectar y remover duplicaciones de código es una actividad a la que debemos aplicarnos si queremos convertirnos en Programadores (así con "P" mayúscula).