Monday, May 19, 2008

Por qué no es lo mismo una aplicación "de escuela" que una aplicación "del mundo real" - II

Además de lo ya comentado en la primera parte de este post, hay otro problema que afecta gravemente a la utilidad de lo que aprendemos en la escuela en el momento de incorporarnos al "mundo real" de la programación: las herramientas.

Utilizar solamente un compilador y un IDE para desarrollar una aplicación actualmente es como utilizar pico y pala para excavar los cimientos de un edificio, ignorando que existen máquinas escavadoras que facilitan el trabajo de los obreros y garantizan un mejor resultado en menos tiempo.

Control de versiones (CVS), gestión de tareas (Issue tracking, bug tracking, etc), pruebas unitarias, generación automática de los productos finales, integración continua, generación de documentación mediante wiki, son todas herramientas imprescindibles para un desarrollador profesional de las cuales nunca oí hablar.

Esta falta de preparación a nivel escolar trae como consecuencia que en muchos lugares estas herramientas sean consideradas innecesarias, o que mucho programadores no se sientan cómodos con ellas y por lo tanto no sean productivos.

A todos esos que como yo no recibieron una formación adecuada los invito a que sufran el proceso de aprendizaje. Cuesta acostumbrarse a utilizar todas estas herramientas que al principio parece que aumentan la carga de trabajo, pero créanme, cuando el proyecto entra en fases más avanzadas se aprecian las ventajas de haber hecho el esfuerzo.

Cuando aparece un bug "misterioso", ya no es tan misterioso cuando se puede comparar la versión que introdujo el bug con la versión anterior, sobre todo si cada revisión del código incluye sólo unos pocos cambios relacionados con una única tarea del sistema de administración de tareas.

Cuando se entrega más de una versión del mismo producto y aparece un bug en una de las versiones, ya no hay que decirle al cliente: "tienes que actualizar a la última versión porque no tenemos el código de la versión que tienes".

Cuando al iniciar el desarrollo de una aplicación se valoraron varias alternativas y se discutió muchísimo y al final se tomaron decisiones, no se pasará nuevamente por todas esas discusiones porque cuando alguien pregunte "por qué no se hizo así..." le podemos decir: mira ESTA página de la Wiki.

Cuando se han ocurrido buenas ideas que ha sido necesario posponer, no quedarán en el olvido, sino que sólo tendrás que ir al Issue Manager y ver las tareas pendientes con baja prioridad.

Y cuando alguien pregunta: ¿cuánto falta para terminar esto? no hay que mentirle ni inventar nada, sólo vas al Issue Manager y miras cuantas tareas faltan por completar, e incluso podrías discutir qué características dejar fuera para terminar antes sobre una base concreta, y no en el pasillo.

Por qué no es lo mismo una aplicación "de escuela" que una aplicación "del mundo real"

Mientras más aplicaciones pasan por mis manos, más lamento la mala preparación que recibí en la escuela con respecto al diseño de una aplicación. La separación del mundo académico y el mundo real en la carrera de "Ciencias de la computación" de La Habana es tan grande que en el transcurso de la carrera no se mencionan cosas como "Arquitectura de 3 capas", "Capa de acceso a datos", "Capa de de negocio", ni mucho menos me enseñaron cómo se diseña un modelo de negocios en una aplicación del mundo real.

En la escuela (al menos en la UH), increíblemente, la mayoría de las aplicaciones que se deben entregar como tarea son aplicaciones sin persistencia, con lo cual nuestros super galardonados y reconocidos profesores nos privaron de la desagradable (pero tan necesaria) experiencia de enfrentarnos a los problemas de OR-Mapping, ni a decisiones sobre si utilizar una base de datos orientada a objetos o una relacional.

Uno de los principales problemas con el que me encuentro al iniciar cada aplicación (y ya van siendo muchas), es el de diseñar un modelo del negocio que no me complique demasiado la vida cuando haya que añadir la persistencia, y que a su vez, me permita la gran flexibilidad de la orientación a objetos, y que no me haga obtener de la base de datos un objeto completo para actualizar una relación del mismo. Me explico mejor:

Supongamos que tengo una clase "Autor" y una clase "Libro", y que en este modelo de negocios que invento yo, un Libro sólo puede tener un Autor mientras que un Autor puede escribir muchos Libros, es decir, que existe la relación 1-n entre Autor y Libros.

Si ésta fuera una aplicación para la escuela, en la cual habrá 10 autores y 50 libros, el "juego de programar" consistiría en crear una clase "Autor" con una lista de "Libros"... ahh, pero que distinto sería todo si pensáramos que nadie invierte dinero en una aplicación que gestion 10 autores y 50 libros, y que en el mundo real esta aplicación debería ser capaz de gestionar miles de autores y cientos de miles de libros y brindando al usuario una velocidad de interacción "aceptable".

Si pensáramos en esto veríamos que con el modelo propuesto parece imprescindible obtener de la base de datos (o servicio de persistencia, en general) una instancia completa de un Autor, ¡incluyendo la lista de todos sus libros!, sólo para añadir un nuevo libro, una operación que, aunque en ciertas aplicaciones podría ser aceptable, es indudablemente ineficiente.

Ahora imagínense hacer este tipo de análisis y tomar una decisión para cada clase en un dominio complejo, sin tener ninguna guía ni ningún patrón al respecto. Imaginen a todos los programadores, al menos los que hacen el curso de "Ciencias de la computación" en la Universidad de La Habana y los que hacen el curso de "Ingeniería Técnica en Informática" en la Universidad Rovira i Virgili de Tarragona. Sólo la Universidad Oberta de Catalunya (UOC) ofrece cierto entrenamiento de este tipo.

No divago más, que el tema es complicado de explicar y la idea central ya está dicha:
No es lo mismo "jugar a programar" que hacerlo de verdad, y en la escuela nos enseñan el juego.