jueves, 16 de diciembre de 2010

Productividad a la espartana

En mi primer trabajo tuve muchísimo tiempo libre. Al principio por estar en la típica situación del junior al que nadie le da bola y después porque dejaron de pagar los sueldos y se decretó una especie de "huelga virtual" : íbamos a la oficina pero no hacíamos nada.

Así que me pasaba 8 horas al día delante de mi terminal Unix (era una espectacular SUN workstation, con monitor de 25 pulgadas, nada mal eh), sin nada para hacer. De puro aburrido, me puse a mirar scripts, a probar comandos, distintos shells, a leer páginas del man y, para cuando se terminó de ir la empresa al tacho, había aprendido bastantes cosas nuevas.

¿Qué pasaría si estuviera en la misma situación ahora? Creo que aún con lo que me gusta mi trabajo no le dedicaría la misma cantidad de tiempo a aprender que en esa época y el principal motivo de esto es que actualmente hay muchas más distracciones disponibles que en mis viejas terminales VT100.

De hecho, hace un tiempo que me venía molestando el tiempo que le estaba dedicando a algunos sitios web, tiempo que sin ser para nada excesivo me parecía que podia dedicar a otras actividades (no necesariamente trabajo: leer un libro, escribir artículos para este blog, etc.). Por lo tanto, decidí implementar una idea que había encontrado varias veces: bloquear esos sitios.

La solución técnica es sencilla: hay que tomar el archivo hosts (qué en Linux se encuentra en /etc y en Windows en \WINDOWS\system32\drivers\etc ) y agregarle líneas del estilo:

0.0.0.0 ole.com www.ole.com www.ole.com.ar

De esta manera, el sitio quedará bloqueado y no podremos acceder más. Por supuesto que así como bloqueamos el sitio podemos desbloquearlo, pero lo importante es que esto exige una acción de nuestra parte y por lo tanto una decisión consciente: ¿quiero ir a leer que dice Carusso Lombardi o prefiero hacer otra cosa?

Adicionalmente, podemos redireccionar los sitios a una lista de cosas para hace, como para que las alternativas a Carusso sean mas claras.

Una cosa más: creo que esto es una excelente idea cuando podemos tomar por nosotros mismos la decisión de hacerlo o no. En cambio, si como jefes bloqueamos el acceso de nuestra gente a cargo estamos dando un mensaje de desconfianza total y además incentivando la búsqueda de maneras de burlar nuestros controles (recuerdo haber escrito un script Perl que cambiaba 12 veces mi password, para burlar una directiva de seguridad que me prohibía reutilizar las últimas 12 passwords, otra vez instalamos servidores proxies para salir a internet sin ser detectados y muchas otras mas que no podemos comentar porque todavía no prescribieron).

Por ultimo, quizás podemos parecer pesados de tanto insistir en administrar de una manera mas productiva nuestros tiempos, o dicho de otra manera de cuanto insistimos en dejar de pavear y perder el tiempo. Bueno, si, es verdad, lo somos.

El problema es que muchas veces nos encontramos diciendo "No tengo tiempo", "No me alcanza el tiempo", "Estoy hasta las manos y no me queda tiempo", cuando en realidad siempre tenemos la misma cantidad: Cada día tenemos 24 horas. El modo en que decidamos como utilizarlo, ahí esta la diferencia.

miércoles, 8 de diciembre de 2010

Saros, Programación de a Pares Distribuida?

Whole Team

Todos sabemos que la forma de comunicación más efectiva que existe es la cara a cara, en un mismo lugar físico, adonde cada uno de los participantes de la comunicación pueda ver las expresiones del otro, sus gestos, y hasta la postura del cuerpo, ademas de escuchar su voz y percibir los cambios de tono.

Por eso una de las practicas centrales que proponía para un equipo de desarrollo eXtreme Programming era Whole Team, todo el equipo, incluyendo usuarios, debían trabajar juntos en un mismo lugar, para que la información fluyera , sin barreras.

En mil y una oportunidades los autores de este blog hemos comprobado cuan cierto es esto.

Outsourcing

Sin embargo, somos realistas, y lo que ha sucedido desde hace varios años es que el modelo económico mundial Globalizado basado en la premisa de buscar fuerza de programación, de análisis, testing o Diseño allí donde sea más barato hace que cada vez sean mas comunes encontrar proyectos distribuidos. Viviendo en paises como Argentina, Chile, Bolivia, Uruguay, Perú, Colombia, Ecuador, Venezuela, Mexico o el mismo Brasil (la unica duda que tengo es España y perdón si me olvido de algún otro País), adonde se recibe cada vez mas proyectos "tercerizados", todos sabemos de lo que hablamos.
De cualquier manera, bienvenido sea el trabajo, ademas porque brinda una gran oportunidad para mostrar la clase de profesionales de primera que tenemos en toda hispanoamerica!.
Las mismas metodologías ágiles lo han terminado aceptando (en algunos casos) y asi existen rios de e-tinta sobre Scrum Distribuido para nombrar una.

Nuevos remedios

Hay una frase de Francis Bacon que es una de mis frases favoritas : "Aquel que no aplica nuevos remedios debe esperar viejos males".

Uno de los problemas más importante ha resolver tiene que ver cuando el equipo de programación esta distribuido. Para ello, para desarrollar sistemas con programadores trabajando en distintos lugares se necesitan nuevas herramientas.

Los que escribimos este blog alguna vez hemos intentado trabajar con herramientas de escritorios compartidos como VNC, TeamViewer, LogMeIn, etc. pero la tasa de refresco de pantalla, la modalidad misma de ver toda la maquina del compañero, no poder hablar al mismo tiempo, todo esto hace difícil el trabajo compartido prolongado y en tiempo real.

Saros

A este respecto hace muy poco nos encontramos con este articulo de Kent Beck que atrajo nuestra atención:
"A Few tips for using Saros for Remote Pairing"

Saros es un plugin de eclipse que permite hacer Pair Programming, programación de a pares distribuida! Prometedor verdad?

Aqui tienen el sitio del proyecto Saros.

Tambien puede ver un video de como se trabaja con Saros.

Tips de Instalacion

Les dejo por ultimo unos tips de instalación, porque hay ciertas cosas que solo funcionan por ahora siguiendo por el caminito de piedras...

1 - El proyecto que compartan lo deben tener ambos desarrolladores ya bajados del repositorio de fuentes o tener muy pocos cambios de diferencia. Lo mejor es empezar con un proyecto nuevo, limpio.

2 - Todos los que vayan a formar parte del pair programming tienen que tener cuentas en el mismo servidor Jabber.

3- La única manera que logre hacerlo funcionar detrás de un entorno VPN con firewall (que impedia acceder a un server Jabber externo) fue primero instalando un servidor de Jabber local en una maquina de la misma LAN, por ejemplo el servidor OpenFire 3.6.4.

4- En las pruebas que hice no funcionó creando las cuentas Jabber por afuera de eclipse. Solo anduvo cuando las creamos desde el menú que instala el plugin en eclipse "Saros\create account", ahí recién el plugin reconocio las cuentas, permitio conectarse y pudimos compartir proyectos.

El plugin esta en un estado de desarrollo beta, pero avanzando a grandes pasos. Al respecto Dice Kent Beck: "...en 15 o 20 años la mayoría de los programas serán escritos a través de colaboración en tiempo real distribuida, así que vale la pena un poquito de dolor ahora para experimentar el futuro."

miércoles, 1 de diciembre de 2010

Sherlock Holmes

"Una vez descartado lo imposible, lo que queda, por improbable que parezca, debe ser la verdad"

Esta frase fue escrita por Arthur Conan Doyle para su personaje Sherlock Holmes y resume el mecanismo de las investigaciones en la mayoría de las novelas policiales: ir descartando posibles explicaciones hasta llegar a la única posible.
Lo difícil, tanto en los casos de Sherlock como en la vida real, es poder descartar N-1 explicaciones, porque N es grande y porque descartar cada explicación no es fácil (creo que no lo podría haber dicho de una manera más nerd o geek, como se dice ahora).

Pero nosotros no necesitamos resolver cosas en la vida real. Sólo necesitamos que nuestros programas anden y existen factores que hacen viable comportarnos como si fuéramos Sherlock Holmes (o el Dr. House, para un ejemplo más moderno).

En primer lugar, las computadoras son determinísticas. Esto significa que si una computadora recibe dos veces exactamente el mismo input el resultado que va a producir va a ser exactamente el mismo. Esta idea no se condice con nuestra experiencia de todos los días (sobre todo si somos usuarios de ciertos sistemas operativos), pero no deja de ser una verdad absoluta, por lo menos para computadoras de nuestra época que no planeen tomar el mundo.

¿Cual es la consecuencia para nuestro método Sherlockiano? Que podemos descartar todas las hipótesis que sean del estilo "no cambié nada y dejo de andar". Si dejó de andar, es por un motivo; quizás nunca podamos descubrirlo; quizás lo haya hecho otra persona, pero existió un motivo (siempre quise poner un punto y coma escribiendo en castellano, es raro porque odio hacerlo cuando programo).

Este es un punto muy importante, porque nos permite liberar nuestro cerebro de mucho trabajo inútil. Si algo deja de funcionar, solo necesitamos ver que cosas cambiaron desde la última vez que anduvo y podemos estar seguros que alguno de esos cambios va a ser el culpable. Teniendo pocos sospechosos, siempre es más fácil descubrir al criminal.

Es aquí donde, además de las características inherentes de nuestro medio, entran en juego hábitos que permiten mantener la lista de sospechosos corta. En el párrafo anterior hay una frase tramposa: solo necesitamos ver que cosas cambiaron desde la última vez que anduvo. Parece sencillo, pero para saber esto se necesita poder determinar primero cual fue la última vez que nuestro programa anduvo y segundo que cosas cambiaron desde entonces.

¿Cómo podemos ser capaces de saber cuándo fue la última vez que nuestro programa funcionó? Si se trata de un problema que aparece en nuestro ambiente de desarrollo, las técnicas que mencionamos aquí son muy eficientes. Si dejamos pasar poco tiempo entre pruebas, es facil saber cuando fue que nos equivocamos. Los tests de unidad en estilo TDD son particularmente eficaces: si corremos los tests cada 10 minutos, un test fallado debe tener un sospechoso bastante obvio.

Si se trata de un problema que apareció en producción o en testing la cosa es más complicada. Hay que recrear los ambientes anteriores para poder verificar en que momento apareció el bug, lo cual a veces es difícil y consume mucho tiempo. Pero nada de esto es nuevo, siempre supimos que dejar llegar bugs a producción es muy caro.

La otra mitad del problema es determinar que cambió para que nuestro programa dejara de andar y aquí entra en acción un hábito muy querido por los autores de este blog: los commits frecuentes. Digamos que logramos determinar que el programa dejó de andar la noche del 24 de julio a las 3AM y que podemos considerar todos los cambios ocurridos cerca de ese momento como sospechosos. Si un programador estuvo modificando código sin commitear durante un mes e hizo commit a las 2AM, todos esos cientos de cambios son igualmente sospechosos. En cambio, si trabajamos de manera de poder commitear todos los días, el conjunto de sospechosos (la cantidad del codigo commiteado) es mucho más corto.

La misma solución se puede aplicar para los problemas en Producción, si no para evitarlos por lo menos para minimizarlos, aplicando las práctica de Integración Contínua y Entregas Frecuentes. La idea es la misma: No esperar a tener mil cambios en la aplicación para pasarla a productivo porque eso implica que cualquier error tiene miles de "sospechosos". Mientras que si uno hace mini-implementaciones y entrega frecuentemente, cada bug tendrá unos pocos "posibles" sospechosos.

Por supuesto, hay variaciones de estos problemas en equipos de trabajos grandes, con gente que modifica a la vez las mismas partes del programa, pero la regla general se mantiene: si algo dejo de andar fue por algún cambio y cuando más fácilmente puedas determinar ese cambio tu vida va a ser más fácil.

Elemental Watson!, Diria Sherlock Holmes (Claro que esa frase no la dice en ninguno de los cuentos o novelas que escribió Arthur Conan Doyle, "Urban Legend" que le dicen).

martes, 23 de noviembre de 2010

Code Smell: Comentarios

El valor de los comentarios es una de las guerras religiosas más antiguas de la programación. Por eso, cuando en una charla o un artículo se menciona a los comentarios como un Code Smell (y nada menos que uno de los citados en la lista original de smells) se suele armar una linda discusión.

¿Cómo puede ser que algo que nos vienen inculcando desde que empezamos a programar sea negativo? ¿Puede ser que todas esas veces que nos negamos a comentar nuestro código teníamos razón? Bueno, para ser exactos lo que dicen Fowler y Beck no es que los comentarios sean un smell en si mismos si no que se utilizan para disimular smells. Es decir, tenemos código que no es tan bueno como debería y en vez de mejorarlo lo comentamos. Como dice Bob Martín en su libro Clean Code, cuando usamos comentarios lo que estamos haciendo es admitir que fallamos en producir código lo suficientemente claro como para no necesitarlos.

Veamos algunos ejemplos de comentarios que se utilizan normalmente y como hacerlos innecesarios y eliminarlos hace mejor nuestro código

1. Comentario obvio
 class Route {
  int id; //the id of this route
 }

¿Y que otra cosa va a ser el field id de una clase Route? Sin embargo, este tipo de comentarios son muy comunes, normalmente porque algún standard corporativo exige que todos los campos tengan un comentario descriptivo.

Hay casos más estúpidos todavía (y juro que he visto esto en la realidad):

 i++; //Increments i

2. Comentario reemplazable por código

 const int MAX_QUEUE = 5; //Max number of queue per process

Aquí el comentario tiene más información que el código, pero sería mucho mejor escribirlo directamente así:

 const int MAX_QUEUE_PER_PROCESS = 5;

Consiguiendo de esta manera documentar no solo la declaración si no el uso de la constante. Otro ejemplo:

 //verify if the request is a cancelation
 if(request.equals(Constants.CANCEL_SMS_JOB) ||
  request.equals(Constants.CANCEL_MMS_JOB) ||
  request.equals(Constants.CANCEL_WAPPUSH_JOB)) {
  //Some code
 }

Lo cual sería mucho más claro si se escribiera asi

 if(request.isACancelation()) {
  //Some code
 }


 boolean isACancelation() {
  return equals(Constants.CANCEL_SMS_JOB) ||
    equals(Constants.CANCEL_MMS_JOB) ||
    equals(Constants.CANCEL_WAPPUSH_JOB);
 }

Además de ser más claro, esta alternativa brinda la posibilidad de reutilizar la lógica en caso de ser necesario.

3. Comentarios históricos
 //2010-09-01 George Creation
 //2010-09-03 John   Add edit funcionality

¿Cuál es el problema? ¿Tu SCM ya no funciona?

4. Trackeo de posición en el codigo
 while(condition1) {
  if(condition2) {
  } else { // end if condition2
  // ...
  // lots and lots of pre...
  // ...
  } //end else conditionN
 } //end while condition1

Este tipo de comentarios parecen totalmente lógicos y de hecho ayudan a guiarse en código complicado. Sin embargo, no son una solución y están enmascarando un problema más grave: el código es demasiado complejo y el método es innecesariamente largo. La verdadera solución al problema de fondo es partir el método en varios métodos cortos y no tener bajo ninguna circunstancia estructuras lógicas que no sean visibles en su totalidad en una pantalla.

Con estos ejemplos no queremos decir que todos los comentarios son inútiles. Pero en general son sospechosos y vale la pena tener siempre en mente la frase de Kent Beck: nunca comentes código de mala calidad, refactorizalo y hacelo excelente.

lunes, 15 de noviembre de 2010

Metaforas del Desarrollo de Software (II)

Introducción

Como hablábamos en (I) una correcta aplicación de metaforas ayuda a encontrar soluciones que se han aplicado con éxito dentro del contexto de la metáfora original, pero cuando la metáfora no aplica....entonces el daño es grande.

En el post anterior hemos revisado alguna de las metáforas que se aplicaron y se aplican al desarrollo de software y que han causado más daño que efectos benéficos. En este vamos a tratar de hacer un repaso por otros contextos e ideas que se ajustan mucho más a lo que realmente es la actividad del desarrollo de software.

Planteamos este tema al foro-agiles de la comunidad Hispano-Americana de metodologías ágiles, y las ideas que surgieron, y el ida y vuelta de metáforas fue de lo más interesante. Vamos a intentar aquí resumir el espíritu de la discusión.

Cuidado con las metáforas

@Carlos Pantelides plantea que no importa cual sea la metáfora se debe conocer del contexto en cuestión para aplicarla correctamente al desarrollo de software.

Un ejemplo, alguien puede afirmar que tal cosa es como una Orquesta Sinfónica. Ahora, esta afirmación sola, así presentada, es ambigua. Si uno no sabe como realmente trabaja una Orquesta Sinfónica quizás malinterprete la afirmación o la simplifique demasiado tomando elementos y soluciones erróneas en lugar de filtrar y aplicar las correctas.

Es claro que una metáfora se la puede utilizar solo como un medio de comunicación "liviano", para trasmitir una idea general, al hablar con un interlocutor que conozca poco del tema. Pero por el otro lado, una persona que realmente conozca del Dominio de la metáfora en cuestión puede estudiarla, analizar las buenas prácticas que dieron buenos resultados en el Dominio original y tratar de ponerlas en práctica en el nuevo dominio.

Decía yo en la discusión:

"Mi idea es que alguien con conocimiento o estudio de la metafora, supongamos por ejemplo Fernando Claverino, analice el dominio en cuestion, , escalar montañas y proponga ideas o soluciones a "extraploar" para aplicar al desarrollo de software. Si despues esas ideas no terminan siendo utiles, practicables o buenas, simplemente se las descarta o no cuajaran dentro de la cultura. Pero no digo que cualquier ñato sin saber escalar, como por ejemplo yo (y sin estudiar del tema), vaya a tirar soluciones a partir de un conocimiento superficial de la metafora , eso es peligroso.

Ahora, si viene Claverino, un grosso del Alpinismo, y me dice...che, mira existe en escalamiento esto llamado "Escalada de a dos", adonde uno hace de soporte del otro y ambos evaluan los riesgos y termina siendo mas rapido, porque ambos evaluan la dificultad de determinadas partes.... y aplican sus conocimientos cruzados. Y si uno es nuevo, lo entrena rapidamente, etc etc.... y me dice, porque no probamos esto en Desarrollo? Yo lo intentaria....

"

Nuevas Metáforas

Pero bueno, vayamos entonces a las nuevas metáforas propuestas como similitud del desarrollo de software por la comunidad ágile (de hispanoamerica=):

  • Grupo de Jazz, Orquesta, grupo de música (Adrian Lasso) : Es similar en el sentido de que igual que en el desarrollo de software, la producción de un grupo de jazz depende de la calidad de los participantes, y el grupo debe tener una fuerte dedicación a practicar. Hay obras más simples y más complejas, igual que hay sistemas más simples y complejos, y el resultado de ejecutarlas depende de la experiencia y calidad del Grupo. Igual que con el desarrollo de software, para hacer un sistema simple no se necesita un equipo muy experimentado con gente de calidad, pero a medida que el sistema se vuelve más complejo, es esencial.
  • Como una obra de teatro (Artful Making, Juan Gabardini) , pueden ver el análisis de esta metáfora y la información de la charla sobre Artful Making de Lee Devin en el blog de Juan http://softwareagil.blogspot.com/2009/07/artful-making.html . Básicamente la idea es que en ambos dominios, a diferencia de por ejemplo la construcción de puentes, el costo de iteración es relativamente bajo, por eso es conveniente iterar (dado el beneficio inmenso del feedback inmediato, la mejorar continua, etc). Agregaba Diego Fontedevila : "El costo de iteración es el costo de reconfiguración (cambiar lo que teníamos) más el costo de exploración (descartar lo que probamos que no sirve). Si ese costo es bajo, vale la pena hacer como decíamos, es decir, hacer software con las manos."
  • Como el trabajo de un artesano (Jose Manuel Beas, software craftsmanship) En el sentido de que la gente que trabaja en Desarrollo se preocupa por la calidad de su producto, práctica y refina sus habilidades y va dando forma a su "obra" de a poco, cuidando el resultado. En definitiva, la calidad de lo "hecho a mano" en contraposición a la producción en cadena. A mi juicio es muy valida porque justamente en desarrollo de software cada sistema que hacemos es totalmente distintos al sistema anterior, como las obras de un artesano, de un artista, no hay dos iguales.
  • El software en si como Urbanismo (es decir, no el proceso de desarrollo sino el software mismo visto como el proceso de desarrollo Urbano, cambiante, reconfigurable, de una ciudad), de Carlos Pantelides.
  • Como la grabación de una película (Federico Freund): Tenemos un período donde se hacen las tomas hasta que quedan bien (en forma iterativa e incremental como en el desarrollo de software), Tenemos actores (programadores) que pueden llegar a repetir las tomas que hicieron por errores que tuvieron o simplemente para perfeccionarlas (corrección de issues), Tenemos un director (que puede ser el lider de proyecto), Tenemos un area revisión de tomas (área de testing), El guionista (puede ser el cliente que define que es lo que desea para su producto), El productor (el owner?), Los que ven la película (los usuarios finales)"
  • Como escalar una montaña (mia y Fernando Claverino) : El equipo tiene un objetivo que es llegar a la cima (entregar el sistema), el lider, ademas de lider es un Guia (coach), aunque muchas veces hay tecnicos expertos que saben mas que el lider de la montaña/Tecnología en cuestión, los distintos caminos de alcanzar la cima son distintas formas de modelar la solucion... Si hay un programador o Analista top, con ego demasiados grandes, suelen ser contrarios a la productividad del equipo porque se cortan solos o quieren imponer su camino hacia la cima, y en la montaña...estar solo redunda en peligros para todos. Yendo a la metodología se pueden subir montañas con equipos "pesados", instalando campamentos intermedios, planificando detalladamente la subida, con equipos grandes, subiendo de a poco. O bien se pueden subir con un equipamiento "ligero" con equipos chicos, ágiles, la exposición es menor ya que todo se hace más rápido. Este último estilo es considerado más elegante y limpio, generalmente lo realizan alpinistas con mucha experiencia. Un tema que mencionó Fernando dentro de esta metáfora es la cordada de 2 personas, donde escala un viejo con mucha experiencia y un joven con mucho potencial. Hablamos en la lista que se parecía de alguna manera a Pair Programming.
  • Hubo otras que se discutieron menos, como ser Escribir una novela de manera cooperativa, metáforas con el arte, la definición de productos de negocios.

Para terminar los dejo con una frase de Juan Gabardini, el prefiere la palabra Analogía en lugar de metáforas, y decía.

Las analogías son resbalizas! Pueden darte ideas, pero esas ideas hay que validarlas!

Material Adicional para ver (Surgido de la thread de foro-agiles)

  1. Emilo gutter sugiere como material una charla de Alistair Cockburn en Agile-2009: http://www.infoq.com/presentations/cockburn-bury-not-praise-agile y un par de charlas de Joshua Kerievsky http://stickyminds.com/Media/Video/Detail.aspx?WebPage=169 y David Hussman de http://agiles2009.agiles.org/es/session.php?id=58 sobre una metáfora de grupo de Musica.
  2. Jose Manuel Beas, metafora de diseño de interiores de Joshua Kerievsky https://elearning.industriallogic.com/gh/submit?Action=PageAction&album=blog2009&path=blog2009/2010/remodeling&devLanguage=Java
  3. Blog de Juan sobre Artful Making: http://softwareagil.blogspot.com/2009/07/artful-making.html

lunes, 8 de noviembre de 2010

Metaforas del desarrollo de software (I)

Lo que el desarrollo de software NO es

El hecho de aplicar metáforas provenientes de una rama de la industria a otra ha sido , al menos durante el siglo XX, una manera común de buscar soluciones ante nuevos problemas que se han aplicado exitosamente dentro del contexto original adonde fueron ideadas. No obstante, estos paralelismos entrañan a veces ciertos riesgos cuando las metáforas son válidas solo de manera superficial o en algún aspecto o contexto en particular y al aplicarlos a la nueva rama producen daños que a veces se extienden por años y se vuelven parte de la cultura de la rama en cuestión.

Vamos a ver a continuación un par de metáforas que se han aplicado erroneamente al desarrollo de software con la (buena) intención de encontrar soluciones provenientes de otros contextos que sirvieran para mejorar la productividad, costo y calidad del desarrollo de sistemas pero que causaron (y causan) gran daño toda vez que se trata de metáforas fallidas, que no representan correctamente la actividad real que se debe llevar a cabo al desarrollar un sistema.

El desarrollo de software como una ingeniería

En el año 1968 Peter Naur propuso que tratemos al desarrollo de software como una Ingeniería. Es decir, se fijo que el desarrollo de software se ocupaba de proyectos, como si fuera un proyecto de ingeniería de construcción de puentes o represas, adonde había un producto final entregable, un cliente y un "Equipo" con ingenieros que se ocupaban de construir el producto. En consecuencia se busco aplicar los valores, principios y buenas practicas que se usaban con éxito en las Ingenierías existentes en ese momento (Civil, eléctrica, metal mecánica, etc.) al desarrollo de software. Fue apropiadamente bautizada como Ingeniería de Software

El impacto que esta metáfora tuvo en el desarrollo de software no es fácil de medir pero nadie puede acusarnos de exagerados si decimos que fue inmenso. Como prueba, hasta algunas carreras universitarias tomaron el nombre y comenzaron a llamar a los recibidos: Ingenieros de Software.

Cuales son los problemas que trajo aparejado el querer manejar al desarrollo de software como un proyecto de Ingeniería?

1- En los proyectos de ingeniería en general el producto final se encuentra claramente definido desde el principio del proyecto y es un objeto real, palpable. Se conocen sus características, sus prestaciones y los criterios de cumplimiento. Por ejemplo, un puente debe tener tales y tales características, se hará de tal material, con tal forma, los cálculos de estructura son estos, debe aguantar tanto peso, etc. y etc..

En contraposición el desarrollo de software se esta construyendo una abstracción completa, algo no palpable, que no existe ni existirá físicamente, a partir de requerimientos vagos y necesidades imprecisas de los usuarios, que se dan cuenta lo que no necesitan solo cuando lo ven funcionando. Los criterios de cumplimiento en general son desconocidos hasta que empieza a ser utilizado en producción.

2- En los proyectos de ingeniería la experiencia de un proyecto se traslada casi directamente al siguiente proyecto porque en definitiva se construye una y otra vez el mismo producto. Es decir, un equipo que se encargue de construir represas, una vez ha realizado la primera, en la segunda la experiencia adquirida es totalmente aplicable y las herramientas y subproductos utilizados son muy similares sino los mismos. En el desarrollo de software cada proyecto de un sistema es completamente distinto al anterior. Si bien parte de la experiencia a nivel técnico de un determinado lenguaje o plataforma es capitalizada en siguientes proyectos la experiencia misma del proyecto no lo es, ya que jamas se construyen dos veces el mismo sistema, como si se hacen n veces represas, puentes o plataformas petroleras.

3- Al estar trabajando con productos físicos, palpables, es relativamente sencillo construir modelos a escala o prototipos con propiedades similares al producto final y probarlos en condiciones que luego son extrapolables a las condiciones reales. Piensen sino en la construcción de un modelo de avión, que se puede hacer en escala, respetando las relaciones entre partes y los materiales. Las pruebas que se hagan luego sobre el prototipo son totalmente válidas sobre el producto final también.

En el desarrollo de software por otro lado ha habido innumerables intentos de proveer herramientas que permitan prototipar sistemas. Para no ser tajantes una enorme mayoría de estos intentos han terminado en un fracaso total. Es muy complejo armar un prototipo de un sistema funcionando de manera que el prototipo contenga todas las propiedades que tendrá el sistema final, porque hacerlo lleva taaanto tiempo como hacer el sistema real mismo. Por ello solo se han encontrado algunos pequeños logros limitados en la prototipación de interfaces de usuarios teniendo el cuidado de entender y hacer entender al usuario que no es real y la navegación de la ui no es la definitiva.

4 - La planificación en un proyecto de ingeniería es imprescindible y un diagrama de Gantt del proyecto provee una excelente herramienta para gestionar el proyecto de ingeniería porque, por un lado los entregables están definidos desde el principio del proyecto y rara vez cambian, las tareas a realizar son conocidas y el esfuerzo que llevan es estimable, y la tasa de avance es, por lo generar, fácil de determinar y se mantiene luego constante hasta finalizar el proyecto, salvo claro algunos imprevistos y cambios, que se minimizan con una adecuada Gestión de riesgos. El cambio en un proyecto de ingeniería no es común y se lo trata por lo tanto como un cambio de alcance de proyecto.

En el desarrollo de software, por otro lado una planificación up-front del proyecto es sólo una proyección ideal de la información al momento de armar el Gantt, los entregables están definidos pero no de una manera detallada , las tareas no son conocidas y estimarlas implica caer en el arte de la adivinación, y la tasa de avance por muy predecible que los gerentes quieran que sean siempre adolece del problema de pareto, es decir el 80% de un sistema se hace en un 20% del tiempo pero el 20% restante lleva el 80% (y muchas veces mucho mas) del resto del proyecto. Por si fuera poco el cambio en el desarrollo de software es algo común, es una parte esencial de desarrollo de un sistema, ya hemos hablado de esto en este post.

El desarrollo de software como una fábrica

Factory

El objetivo de La producción de una Fabrica es producir uno o unos pocos productos de forma repetitiva, hay relativamente muy poca innovación o resolucion de problemas en el proceso. Tiene un proceso conocido de antemano, inputs repetibles y outputs predefinidos. La especificación del producto a producir esta perfectamente definida de antemano. Los trabajadores de una fabrica realizan una y otra vez la misma tareas o un conjunto limitados de ellas, acotadas y sin necesidad de aplicar gran conocimiento, utilizando herramientas tradicionales o no pero probadas miles de veces en cadenas de producción. Son los trabajadores de la era de la revolución industrial.

Desarrollo de software

Construye un solo producto por primera y UNICA vez, lo cual implica un monton de innovación y resolución de problemas a la vez y nunca se construye otro igual (una copia digital alcanza). Muchas veces parte del desarrollo implica definir el proceso, las entradas son múltiples y variables y los outputs no se conocen con certeza hasta terminar el sistema. La especificación del producto a construir es imposible de hacerla de antemano. Los trabajadores del desarrollo de software, sean programadores, Analistas, Testers o especialistas en infraestructura, son trabajadores altamente calificados, su tarea se basa en aplicar gran cantidad de conocimiento en la resolución de problemas y el diseño de modelos abstractos de desarrollo, utilizando herramientas y tecnologías nueva, cambiantes y muchas veces poco testeadas. Son trabajadores de la Era del Conocimiento.

Es por todos bien conocidas las consecuencias que ha traído la aplicación reciente de esta metáfora sobre todo en la realidad devaluada de Latinoamerica y varios países del mundo "en vias de desarrollo", a saber:

La Aparición de las llamadas "Factorías de Desarrollo de Software", o "Software Factories" que equiparan a los Programadores con obreros trabajando en fabricas (a más "obreros" más productividad, sin tener en cuenta la calidad del trabajo o el nivel de experiencia), adonde se les entregaba una especificación del sistema que tenían que "Construir" (palabra también proveniente de la misma metáfora), se les daba el Diseño del producto que debían seguir y se les aconsejaba "No Pensar".

Juro que en una factoría de una empresa en la que trabajé evaluaron la posibilidad de contratar dos turnos de desarrolladores para contar con una fuerza de desarrollo de 24 horas!!!

A aquel que sabe y conoce lo que se necesita para desarrollar sistemas de calidad la frase anterior le debería haber puesto la piel de gallina.

Buscando una salida

En conclusión, dos de los principales Contextos-Modelo elegidos para tomar soluciones para el desarrollo de software han llevado a aplicar numerosas técnicas fallidas, principios y modelos organizacionales que han causado gran daño a la industria y que todavía al día de hoy siguen creando confusión hasta en la forma de tratar a los trabajadores del desarrollo de software.

La historia no estaría completa si no buscáramos alguna salida para esta encrucijada. En un próximo Post contaremos las soluciones que plantean la gente del foro ágil de Hispanoamérica, foro-agiles, veremos entonces algunas metáforas que aplican un poco mejor al desarrollo de software y como han surgido y pueden seguir surgiendo de allí soluciones realmente válidas.

lunes, 1 de noviembre de 2010

Liderazgo (II)

En el post anterior hablamos un poco de cuales son las características deseables en un Líder, parte de una discusión que se dio en la lista de metodologías ágiles y Scrum , llamada "foro-agiles" (un grupo de yahoogroups). Vamos ahora a ver como encara este tema de como debe ser un líder de un equipo, Gerald Weinberg, autor de entre otros excelentes libros de "The Psychology of Computer Programming.", "Secrets of Consulting: A Guide to Giving and Getting Advice Successfully", etc.
El libro de Weinberg, "Becoming a Technical Leader" es un libro muy interesante adonde el autor aborda el tema del liderazgo desde una óptica poco común. En uno de los capítulos habla de la relación entre el líder y las personas que están a su cargo, para plantearse en síntesis como tiene que ser esta relación, definiendo la conclusión en forma de ciertas "leyes" sobre el liderazgo.

Comienza contando sobre un test que se realizaba en un curso sobre Liderazgo y Management Tradicional. En él se solía plantear una determinada pregunta proponiendo lo que es básicamente:
El dilema por excelencia del liderazgo

Usted esta a cargo de un equipo, y tienen una tarea a terminar. Si el éxito de la tarea se encuentra amenazado, usted probablemente:
a. Pondrá la finalización de la tarea por encima del bienestar de su gente.
b. Pondrá al bienestar de la gente por encima de la finalización de la tarea.
c. Balanceará la importancia entre su gente y la tarea.
d. Escapa de la situación.
e. Ninguna de las anteriores.

Una tarea debe ser completada con un cierto resultado dentro de un tiempo determinado o sino alguna consecuencia negativa sucederá, consecuencia que en principio solo conoce el Líder. Que actitud tomar?, Si uno requiere que todas las personas del equipo trabajen tiempo extra o hagan lo que sea necesario hasta terminarlo están poniendo a la tarea por encima de las personas. Si uno por otro lado comparte con su equipo las consecuencia del no cumplimiento, así como también el motivo por el cual tiene que ser realizada la tarea permitiendo al equipo decidir ellos mismos cuanto trabajar, como, e incluso si van a terminar la tarea entonces están poniendo a la gente por encima de la tarea.

La pregunta, que todos deberíamos hacernos es, Está bien planteado el test? Existe realmente una dicotomía entre tareas y personas? Porque en realidad la tarea que debe hacerse es realizada para conseguir un objetivo para otras personas, es decir que, en realidad el dilema es elegir entre un grupo de personas, diríamos los Interesados (stakeholders) en que se complete la tarea y las personas del equipo que debe realizarla, llamemoslos, Los trabajadores.

El capitulo en cuestión es sumamente interesante, y aquí van algunas de las lecciones más importantes que se destilan de él, que nos ayudan, de alguna manera, a razonar sobre el dilema.
Algunas Leyes sobre Liderazgo

Ley Numero 4: El líder que no le importa la gente no tiene a nadie a quien liderar, a menos que sus seguidores no tengan alternativa.

Ley Número 7: Hay muy pocas tareas que sean realmente tan importantes como para que justifiquen sacrificar las futuras posibilidades de las personas que están realizando el trabajo.

Ley numero 9: Para ser un líder efectivo debemos tener en cuenta y bien presente en todo momento los motivos y sentimientos de todas las personas afectadas por la tarea: los interesados y los trabajadores.
La Solución (como nosotros la vemos)

En mi opinión entonces, un líder efectivo puesto ante el dilema antes mencionado, encontraría la solución eligiendo e. Ninguna de las anteriores:
Primero debe pedir, obtener y entender los motivos, objetivos y sentimientos detrás de los Interesados en la tarea. Luego compartir con el grupo los motivos y consecuencias de la mismas, para que de manera seria y profesional todos tomen la responsabilidad de llevarla a cabo. Y teniendo en cuenta que nunca vale la pena sacrificar algunas personas por otras, conseguir llevar adelante la tarea dentro de tiempos y parámetros razonables para ambos grupos (la única excepción, claro, es que haya riesgo de vida, en este caso obviamente se puede sacrificar el bienestar de un grupo de manera temporal si la tarea salvará vidas).

Deje para terminar este post mi ley favorita:

Ley numero 10: Si tu eres un Líder , La Gente ES tu trabajo. No hay ninguna otra cosa que merezca tu atención.