domingo, 12 de septiembre de 2004

No es mi culpa

"Si culpas a tus empleados, eres un mal manager. Los contrataste, los aceptaste, los supervisaste y dirigiste su entrenamiento. Eres el responsable. Si no te gusta lo que está sucediendo, observa tu propio comportamiento. Pero, si hay crédito para dar, es de ellos." Gerald Weinberg

Sigo con la serie "No hagas lo que yo hice" que inicie hace un tiempo. Esta vez se trata de un pensamiento que he tenido más de una vez: "No es mi culpa". Esta es una de las cosas más nocivas que uno puede pensar cuando trabaja en equipo, mucho más cuando coordina un equipo.

En un proyecto tuve que trabajar con dos estudiantes que estaban haciendo sus primeros pasos en el desarrollo de software. Conocían las herramientas de desarrollo que estábamos utilizando pero no habían participado nunca de un proyecto más allá de los trabajos para la universidad y carecían de algunos conocimientos importantes como diseño orientado a objetos.
Yo había iniciado el desarrollo del proyecto definiendo algunas cuestiones arquitectónicas para el manejo de la persistencia, la validación de errores y algunas otras cosas. Luego debí dejar el desarrollo para ocuparme de otras tareas, pero seguía el avance del proyecto. El problema no era sólo que el avance no era el esperado. La sensación que tenía en aquellos momentos cuando me ponían al tanto del estado del proyecto era que se estaba haciendo todo mal.

Una y otra vez se perdían modificaciones en el código por un mal uso de la herramienta de manejo de versiones, y siempre el origen de todo era, supuestamente, alguna falla de SourceSafe. Yo pensaba, "Vamos, SourceSafe tiene sus problemas pero sé que se puede hacer un check-in sin perder información si lo hago bien...". Luego observaba que el código estaba repleto de declaraciones de atributos enteros con signo de 16 bits (Integer en Visual Basic) cuando los valores posibles para esos atributos iban mucho mas allá de los límites de este tipo de datos. "¡Genial! Ahora nuestra aplicación es un campo minado de posibles errores de overflow esperando estallar cuando quiera utilizar un valor tan grande como... 32679". Los casos de uso que supuestamente estaban terminados, y que debían estar listos hace 2 semanas, tenían errores tan grotescos que no soportaban un smoke test mínimo. En realidad, no es que saliera humo al probarlos. ¡Se desataba un espectáculo de fuegos artificiales en el cielo cada vez que se ejecutaba la aplicación!

"¡¡¡GGRRRR!!! ¡Están haciendo todo mal!"

Es terrible tener ese pensamiento. Es injusto porque cuando uno trabaja en equipo siempre tiene algo que ver con los resultados y es poco práctico porque si siempre pienso que la culpa de todo la tiene otra persona, es poco lo que puedo hacer para mejorar las cosas. Y, al final, no hago nada.

¿Por qué no se capacito a esas personas para manejar las herramientas de control de versión antes que tengan que utilizarlas en un proyecto?
¿Por qué no se replanifican las iteraciones si vemos que la realidad no se adapta a nuestros planes?
¿Por qué nadie verifica que las personas que toman decisiones de diseño están capacitadas para hacerlo o cuentan con alguien que las ayude para hacerlo?
¿Por qué no se analizan cuales son los motivos de los errores, cuales son las fallas en nuestra manera de trabajar, como podemos merjorarla, que técnicas podemos utilizar?

Hacerse este tipo de preguntas puede ser doloroso. Porque los problemas de un proyecto pueden ser el reflejo de las limitaciones propias. Es mucho más fácil asignarle las culpas a otras personas, más aún si son nuevas en la empresa o con menos responsabilidad. Eso no está bien.

domingo, 5 de septiembre de 2004

Leer, leer, leer

En muchos momentos del día, casi inconcientemente, pienso en temas relacionados al desarrollo de software. Cuando observo algún problema en mis tareas diarias, analizo la situación más allá del escenario puntual que me toca vivir. Inevitablemente comienzan a nacer en mi mente relaciones de un tema con experiencias pasadas, con comentarios de amigos y colegas, con material que pude leer en el pasado.

Cuando algún tema ocupa mi mente un tiempo considerable es cuando pienso que podría tener mis ideas más claras si las escribiera y este sitio termina siendo el destino para ellas. Hace poco encontré uno de esos temas. La gran mayoría de aplicaciones que he desarrollado son aplicaciones empresariales, que soportan algún proceso de negocio para alguna empresa, que hacen uso intensivo de base de datos para guardar información y que deben convivir e intercambiar información con sistemas diversos en plataformas diversas.

Una y otra vez he observado que cuando se inicia el desarrollo de este tipo de aplicaciones se le da gran importancia a la manera de guardar los datos. Cualquier equipo de desarrollo con algo de experiencia en este tipo de aplicaciones conoce la importancia de aislar la funcionalidad relacionada con el acceso a datos de alguna manera.
Simplificando, lo que se intenta resolver es donde estarán las sentencias SQL. Puede existir un objeto que se encargue de armar las sentencias, puede existir una capa de persistencia que lo haga o se puede utilizar algún framework de persistencia open source para hacerlo. El punto es que he visto que gran parte de las definiciones arquitectónicas de una aplicación empresarial tienen que ver con esto. El objetivo es que sea fácil buscar, modificar y eliminar datos, y que no haga escribir mucho código para hacer un ABM (alta/baja/modificación) para una entidad. Entonces el desarrollo de una aplicación se limita casi a un copiar y pegar de una pantalla porque la manera de acceder a los datos está bien definida.

Pero el problema es que las aplicaciones rara vez se limitan a buscar, modificar y eliminar datos. Siempre hay lógica de negocio compleja, cambiante, con sutiles detalles que hacen que los distintos casos a considerar sean muchos.

Recuerdo, por ejemplo, un proyecto en el que participe donde una de las funcionalidades más criticas era un proceso de facturación por lotes que debía considerar muchas variantes. Es la típica empresa de servicios que factura a sus clientes periódicamente pero que siempre existen muchas reglas que hacen variar el monto facturado. Extrañamente, en este proyecto las definiciones arquitectónicas tenían que ver con el manejo de la persistencia y no sobre como hacer flexible el proceso de facturación para permitir variación en las reglas que rigen ese proceso.

El problema de centrarse en el acceso a datos es que se pierde de vista otros aspectos más importantes en algunas aplicaciones y se termina con el código de la lógica de negocio con gran acoplamiento, difícil de modificar, de probar y con funcionalidad repetida.

Es llamativo lo nocivo que pueden resultar algunas recomendaciones valorables cuando son simplificadas. Por ejemplo, Ivar Jacobson en Object-Oriented Software Engineering: A Use Case Driven Approach propone la representación de información, comportamiento y presentación de un sistema con distintos tipos de objetos. Los objetos de interfase encargan de la presentación, los objetos entidad tratan la información y los objetos de control representan el comportamiento.
El patrón MVC (model view controller) propone algo similar. El problema existe cuando se siguen mecánicamente estas sugerencias. Los objetos modelo (o entidad) son objetos bobos que solo tienen datos y el controlador es una ensalada de lógica difícil de modificar de extender y de probar.

En un momento pensé en escribir sobre este problema y hacer un ejemplo con diagramas, y tal vez hasta código, porque me resultaba un tema medianamente interesante. Pero algo sucedió antes que lo haga. Llegó a mi escritorio el libro Patterns of Enterprise Applications Architecture de Martín Fowler. Cuando comencé a leerlo vi todos estos temas tratados detalladamente incluyendo alternativas con pros y contras, además de soluciones a otros problemas que se presentan recurrentemente en el desarrollo de aplicaciones de este tipo. Y entendí que no tiene sentido que yo escriba al respecto porque difícilmente tenga algo para agregar más allá de lo que dice este libro. Me basta con recomendarle el libro a cada desarrollador de aplicaciones empresariales.

Lo que me marcó este hallazgo fue algo que he visto antes. Uno piensa en algo y le da vueltas al asunto. Y las respuestas están muchos más cerca de lo que uno cree. Son cosas que ya han pensado otras personas, sólo hay que leer para conocerlas. Leer. Leer. Leer. Tenemos que ampliar el espectro de nuestro conocimiento y prestarle atención a temas que no nos resultan útiles inmediatamente. Si uno no lee, se encuentra lanzado manotazos en la oscuridad cuando algún problema escapa de lo usual.
Cuando uno se mantiene informado sobre muchas cosas, comienza a conocer la punta del ovillo de cada tema y sabe donde buscar más información.

Por ejemplo, saber que existe algo que se llama Gestión de Configuración permite buscar herramientas de Gestión de Configuración, procedimientos de Gestión de Configuración, recomendaciones para la Gestión de Configuración en proyectos de todo tipo, averiguar como hacer un manual de Gestión de Configuración y hasta conocer patrones de Gestión de Configuración.
No saberlo nos lleva a juguetear con CVS o SourceSafe, y tratar de reinventar la rueda, mientras Pepe pisa por enésima vez las modificaciones de Juan y todos están tratando de adivinar que versión del producto está instalada en el cliente.

Esto es casi una frase hecha pero es real. El desarrollador de software es un trabajador del conocimiento. Es esencial para nuestro trabajo, es “el” elemento diferenciador, tanto para personas como para empresas en el rubro. El conocimiento no es sólo lo que hace que una persona sepa como resolver un problema y otro no. El conocimiento también es necesario para encontrar nuevas soluciones y esa búsqueda puede ser una diferencia abismal en tiempos y resultados.

Dada la importancia que tiene el conocimiento en nuestra profesión hay algo que me llama la atención y, para ser sincero, me molesta. He tenido la posibilidad de conocer empresas pequeñas y grandes, dedicadas al desarrollo de software específicamente o áreas de desarrollo de empresas de servicio. En ninguna de ellas he visto una biblioteca que llamará mi atención. En ninguna. Me resulta extraño que mi biblioteca sea la más amplia que he podido conocer con respecto a desarrollo de software. Si veo algún libro de administración de un servidor Exchange o alguno de PL/SQL o Java, pero no veo a McConnell, Cockburn, Weinberg, Beck, Fowler, Booch. Humprey. No están.

Posiblemente los resultados positivos de comprar libros no se ven nítidamente en los resultados de facturación a fin de mes y puede pensarse que los costos son inaceptables, pero con una visión más amplia se puede observar que los beneficios son abismales. En lo personal, los costos de no leer me resultan inaceptables