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.