viernes, 25 de enero de 2008

Object Classes en Structured Programming!!

En mi post de http://objectmodels.blogspot.com/2008/01/acm-classic-books-series.html comenté que me llamaba la atención que en el índice del libro de Structured Programming había una entrada que decía "Object Classes" lo cual despertó mi curiosidad y hoy pude comprobar que realmente habla sobre Classes y Objetos! Si, en el clásico de programación estructurada del año 1972, se estaba hablando de Objetos y más aún de Simula-67, ¡que loco!.
Claro, este capítulo lo escribió Ole-Johan Dahl, uno de los creadores de Simula-67 junto a Kristen Nygaard

jueves, 24 de enero de 2008

¿Por qué Computer Science?

Si hay algo que al principio me rompía soberanamente las ... (ustedes saben que) cuando me preguntaban mi profesión y les respondía "Licenciado en Ciencias de la Computación", es que el "preguntón" no entendía lo más mínimo qué había dicho o de qué trataba la cosa, motivo por el cual tenía que recrear mi respuesta con un "Analista de Sistemas" o "Ingeniero en Sistemas".
No es que tenga nada en contra de esas profesiones, de hecho, cuando empecé a estudiar la carrera en Exactas, en la UBA, no tenía la más mínima idea de la diferencia entre esta y las otras, algo que creo que le sucede a la mayoría (en rigor de verdad, sabía que esta carrera era de "más bajo nivel" cosa que me interesaba porque amaba el Assembler), pero es feo que la profesión de uno no pueda ser reconocida y que haya que cambiarla por otra para que te entiendan. Es como que te pregunten cómo te llamás y digas "Hermán", y como suena raro (quizá el tipo del registro tipeo por error la m en vez de la n) tengas que decir, "bueno, Hernán" y de esa manera quedán todos conformes (cosa que debo admitir dolorosamente que también me sucedió mientras viví en EE.UU. donde tenía que pronunciar mi nombre como una especie de "Gernan" sajón puesto que el Hernán con sonido Español no lo podían resistir).
En fin, ¿a qué viene todo esto?, a que hoy estaba pensando por qué la carrera de "Computer Science" no es conocida, pero sí las otras. La verdad que no creo saber el motivo, pero algo que se me ocurrió es que "Ciencias de la Computación" suena un poco cursi, un poco no definido, no maduro. ¿O acaso a la Matemática la llamamos "Ciencias de los Números"? ¿o a la Física, "Ciencias de los Cuerpos" (no me mal interpreten :-), ¿o a la Química "Ciencias de los Minerales"? o a la Biología... bueno, ¿entendieron el punto no?.
Quizá la Matemática al principio era conocida como "Ciencia de los Números" puesto que aún no se había establecido como una disciplina reconocida y madura, quizá lo mismo pasó con la física, pero es solo una conjetura, no puedo asegurarlo. Imagino que hasta que se uso la palabra Matemática para nombrarla deben haber pasado unas cuantas centurias desde que se empezó a "hacer matemática".
¿A qué me lleva esto?, si tiene algún sentido lo que estoy diciendo, a que quizá habría que buscar una única palabra para "Ciencias de la Computación", algo así como "Algorítmica" o "Computabilidad" o alguna palabra similar. Quizá solo podamos sintetizar esta idea en una sola palabra cuando realmente sepamos qué es "Ciencias de la Computación" y todos nos pongamos de acuerdo en su alcance, aunque últimamente los límites de todas las ciencias son cada vez más difusos.
Pero de algo estoy seguro, si me llegasen a preguntar mi profesión y pudiese responder "Algorítmica" o "Computabilidad", seguramente el que preguntó no sabrá qué significa pero al menos no dudará en pedir algún sinónimo y me sienta obligado en reemplazarlo por "Analista de Sistemas" y simplemente porque es una palabra. Sería bueno también que al decir "Algorítmica" no se produjera ninguna duda, pero eso imagino que sucederá cuando las "Ciencias de la Computación" estén tan maduras como lo estuvo la Matemática cuando la empezaron a llamar así.
Y por último, para poner la nota depresiva, si es que el actual escrito no lo es, también terminé pensando en si tiene sentido preocuparse tanto por esto, total actualmente las carreras de "Ciencias de la Computación" se asemejan cada vez más a una de "Ingeniería en Sistemas", total lo importante es generar programadores porque hay mucha demanda....
(No se preocupen, que haya tenido que usar otro nombre en USA, que tenga que decir otra profesión cuando me lo preguntan o que sienta que la carrera en la cual enseño pierde cada vez más su identidad no ha producido en mi el más mínimo problema de auto estima... o por lo menos eso creo! FREUD!!!!!)

ACM Classic Books Series

Ya salió (y quizá hace rato pero recién me entero) la lista de los 20 libros más votados en la encusta hecha por la ACM de Computer Science. Pueden verla aca: http://portal.acm.org/toc.cfm?id=SERIES11430&type=series&coll=ACM&dl=ACM
Lo bueno de esta lista es que ya hay algunos libros digitalizados disponibles para bajarlos y están en proceso de hacer disponibles otros más. Yo ya me bajé algunos que voy a intentar leer, aunque más no sea hojear los índices, cosa que hice con "Structured Programming" de Dahl, Dijkstra y Hoare, con el cual me llevé una gran sorpresa al ver el título "Object Classes" que se encuentra en la sección "Hierarchical Program Structures"... hmmm... ¿"Object Classes" en un libro de programación estructurada? ¿No les pica el bichito de la curiosidad?.
A mi si, así que ya mismo me voy a fijar de que se trata... stay tuned, quizá me dan ganas de comentar que ví :-)

miércoles, 23 de enero de 2008

Sobre diseño y algo más

Ya estoy de vuelta de mis vacaciones y algo en lo que estuve pensando la última semana fue sobre lo que se entiende por diseño. Se me metió esa idea en la cabeza y quería compartir algunas cosas de manera completamente desordenada, tal como me salen, que pensé y que vengo pensando y conversando con otros hace rato.
Una de ellas es como últimamente se observa cada vez más en nuestra profesión es la confusión del fin con el medio, donde el medio pasa a ser el fin (algo muy común en nuestra época en todo tipo áreas). Es muy común que cuando a gente que estoy entrevistando le pregunto si saben diseñar utilizando objetos respondan que sí, que saben UML. Esto es similar que a un arquitecto le pregunte si sabe diseñar edificios y este responda que sí, que sabe usar el CAD. Queda claro con esta respuesta que dicha persona no sabe qué es diseñar.
Pero como dije, es muy común que se produzca esta confusión en gran medida a las grandes falencias que existe en la educación en nuestra profesión, cada vez más vapuleada por el frenesí de tener todo listo lo más rápido posible. O sea, ese frenesí se traslada a la enseñanza donde "enseñar diseño" pasa a ser enseñar una herramienta puesto que es mucho más rápido aprender a usar una herramienta que manejar la teoría, la esencia de diseño. Tampoco puedo dejar de nombrar la presión que las grandes corporaciones siguen incrementando sobre las universidad, a las cuales realmente les interesa que utilicen sus herramientas (tienen que vender, tienen que lograr adeptos) y ese interés hace que nuevamente se confunda el medio (o la herramienta) con el fin. Ya no se enseña "Base de Datos" se enseña "SQL Server", ya no se enseña "Objetos", se enseña "Java" o ".Net". En fin, un poco de catarsis que hago que muestra una triste realidad y que termina siendo uno de los motivos de los graves problemas que existen en el desarrollo de software.
Volviendo al tema principal de este post, el mismo surgió en mi cabeza cuando quise recordar la definición de "Diseño" o "Diseñar". La verdad que no recuerdo una definición exacta, no recuerdo que definición me dieron en la facultad si es que lo hicieron. Tampoco estuve haciendo mucho reasearch al respecto, quizá debería haber ido al libro de Rebecca, Meyer o Booch, pero no lo hice. Lo más sencillo, o por lo menos lo que tenía a mano, era ir la wikipedia y buscar que definición describe. En ella se puede leer: "Software design is a process of problem-solving and planning for a software solution. After the purpose and specifications of software is determined, software developers will design or employ designers to develop a plan for a solution. It includes low-level component and algorithm implementation issues as well as the architectural view."
La verdad me parece una definición muy pobre y llena de falencias. Falencias empezando por creer que la especificaciones del software se "determinan" en algún momento, muy pobre porque no queda claro finalmente qué es diseñar, más allá de ser un proceso para "resolver problemas y planificar una solución".
Personalmente me cuesta mucho definir ahora y bien qué es diseñar, pero si estoy seguro que un buen diseño de un sistema hará que sus desarrolladores tengan una vida mejor y menos traumática. Para mi diseñar es toda tarea que se hace durante el desarrollo de un sistema orientado a mejorar los objetivos que se propusieron al realizar dicho sistema. El problema es que hay varios tipos de objetivos, aquellos orientados al desarrollo per se como el mantenimiento y la evolución del sistema, objetivos orientados a la ejecución como la performance, la independencia de la plataforma, objetivos orientados a la usabilidad del sistema, etc.
De todos estos objetivos, el que más me importa hablar ahora es el relacionado al desarrollo del sistema, puesto que es ahí donde se puede ver una gran diferencia con otras disciplinas, básicamente porque hay una diferencia muy grande en construir un sistema y construir cualquier otro tipo de producto como una casa, un auto o un electrodoméstico. La principal diferencia es que en estos producto que acabo de mencionar, una vez construidos no se los puede modificar (o no en gran medida). O sea, una vez que salió el Renault xx a la calle, todos serán iguales y no se los podrá modificar. Si hay que hacer algún cambio, por ejemplo que ahora el auto soporte andar sobre hielo, se deberá esperar a toda una nueva generación de autos, los que ya existen no cambiarán. Pero la necesidad de una nueva funcionalidad no tiene porque ser el disparador de una nueva "versión" de autos, también los autos, como cualquier producto, tienen errores de diseño.
Recuerdo un amigo que compró justamente un Renault muy caro (no recuerdo el modelo) que tenía la luz de stop superior ubicada de tal manera que dificultaba la visión por el espejo retrovisor. Claramente un error de diseño de usabilidad. Por supuesto este error no puede ser resuelto en ese auto de mi amigo, no se puede romper el vidrio trasero y el techo para poner la luz en otro lugar y así solucionar este error de diseño; si quiere una solución hay que tener otro auto físicamente hablando que tenga la luz en otro lugar (¡y rogar que ese otro lugar no sea molesto tampoco!). ¿Qué consecuencias trae esta característica?, que los diseñadores de autos no se preocupen por diseñar el auto de tal manera que si surge un error o nuevo requerimiento, este pueda ser solucionado en el mismo auto, en el auto que ya tiene el usuario. Si surge un problema no previsto, un requerimiento nuevo o un error de diseño, se diseñará su solución en otra "versión". Y sacar otra versión de una auto cuesta dinero, no es fácil cambiar matrices, para una linea de producción y empezar otra, etc.
Sin embargo esto en el software no es así, justamente la maleabilidad del software, una de sus características esenciales de ser fácilmente cambiable, según nombra Brooks, obliga a los desarrolladores a tener en cuenta este característica al momento de diseñar. Esto nos puede llevar a pensar que lo mejor es tratar de resolver todo problema que pueda surgir antes de terminar el producto y así caer en un "design paralisis" (muy común en sistemas) y no terminar nunca. O que es conveniente tener diseños preparados para realizar cambios fácilmente, o sea tratar de adivinar el futuro sobre que puede llegar a cambiar en un sistema y por lo tanto diseñarlo para que el impacto de dicho cambio no sea grande. Utilizando un analogía con el ejemplo del auto, sería adivinar que nos van a pedir que el mismo funcione sobre hielo o prever que habrá errores de diseño como esa maldita luz de stop que quedó mal ubicada y que demuestra en definitiva que nadie se subió a manejar el auto antes de que saliera a la venta.
Esta es la linea de pensamiento que muchos tienen y que muchos proponen puesto que están acostumbrados a traer ideas de otras disciplinas, a veces porque no se entiende el problema y a veces porque se quiere forzar la solución. Sin ir más lejos, el Gang of Four en el libro de Design Patterns, proponen a estos como una solución a este problema, proponen diseñara para el cambio. Esta manera de pensar lleva a muchos a crear los grandilocuentes diagramas de clases usando UML como si estos fuesen el diseño que permitirá resolver cualquier cambio que surga. No existe falacia mayor que esa, un diagrama de clase nunca ayudará a tener un buen diseño y menos a resolver posibles cambios en el software puesto que el mismo es una vista "estática" del sistema y peor aún, hecha sobre un medio que no "ejecuta", donde nunca puede surgir algún error. Esta concepción de tener resuelto todo antes de empezar es válida en otras industrias pero no en la nuestra.
Otro problema que tiene esta linea de pensamiento es que debido a que todo tiene que estar resuelto antes de empezar a "programar", se utilizan todo medios satélites para crear esos artefactos que supuestamente ayudarán a dicha tarea. Se utilizan enormes diagramas UML, inentendibles algunos por cierto, con una notación que es tan compleja como inútil. Enormes documentos de especificaciones que nunca nadie lee y luego nadie modifica cuando se descubre que algo estaba mal. Se le da tanta importancia a estos artefactos que se desvía la vista de aquel principal, el código. Se desvía tanto la atención de este que pasa a tener más valor un diagrama UML que el código mismo, claro el primero fue hecho por un "diseñador" o "arquitecto", el segundo por un simple "programador", como si estuviésemos comparado el blue print del auto hecho por un ingeniero con el metal soldado por el pobre obrero de la linea de producción, nada más lejano de la realidad pero que sucede debido a tratar de copiar los modelos utilizados en otras industrias.
"Metodologías" ágiles como XP, aconsejan olvidarse del problema del cambio y utilizar otro tipo de técnicas que permitan, cuando llegue el momento, realizar cambios y asegurarse que todo siga funcionando correctamente como así también elevar el status del código a su máximo nivel. Algunas de estas técnicas son Test Driven Development, Code Ownership, Continuous Integration, Refactoring, etc.
En el caso de los cambios, la solución que proponen se basa principalmente en que no hay manera de predecir que cambios se realizarán, básicamente que no es fácil predecir el futuro, tesis con la que concuerdo 100%, no por que lo pueda demostrar formalmente sino más bien por resultados empíricos, que en criollo se traduce como "experiencia". Sin embargo este "consejo" que nos da Kent Beck por medio de XP tiene su lado peligroso, puede ser mal interpretado y se concluya que "no hay que diseñar", que no es importante diseñar como una vez dijo el "no respetable" (desde mi punto de vista y otros tantos) Martin Fowler en su key note de OOPSLA 2005.
El caso de elevar el status del código se basa principalmente en entender que no hay mejor lugar que este para mantener toda la información necesaria del desarrollo. Claro está que en aquellos lenguajes "textuales" como Java, .Net, etc. donde aún se siguen utilizando editores de texto para programar como si siguiéramos en la década del '60 programando FORTRAN en una green screen esto es difícil de imaginar. En un ambiente de desarrollo real, pensado para eso justamente, para desarrollar, como Smalltalk, es mucho más fácil de ver puesto que todos los elementos de un programa están reificados y al alcance de la mano. ¿Para qué perder tiempo modificando diagramas UML para luego modificar el código (siempre que no haya cometido el estúpido error de generar código automáticamente desde los diagramas), compilarlo y por último arrancar el sistema de nuevo para ver si arregló algo el cambio realizado, si puedo directamente sobre el sistema corriendo modificar mis objetos y ver el resultado?. Hay gente de sistemas que se olvida para que fueron hechos los sistemas, para simplificarnos la vida, no para hacerla la complicada. Sin embargo aún hay propuesta que se asemejan a pedirle a un diseñador gráfico de aplicaciones web que antes de usar alguna herramienta de edición HTML, escriba diagramas que definan el formato de las páginas web como algunas metodologías escolásticas lo proponen, o que a un vendedor le pidan que realice diagramas de contenido antes de ir directamente al PowerPoint y crear la presentación que utilizará para realizar su venta. Es absurdo por donde se lo vea.
Resulta que si cuando se desarrolla, el modelo que se está creando es "similar" a la realidad que se está representando, en definitiva que el diseño de mi sistema es similar al diseño que tiene el dominio de problema que se está sistematizando, y dicho modelo se está representando directamente en un medio activo, vivo como es Smalltalk, los cambios que surjan en el dominio serán de fácil e inmediata aplicación en el modelo, que en definitiva es el sistema.
Test Drive Development nos permite realizar estos cambios con mayor confianza y seguridad puesto que si metimos la pata algún test TIENE que fallar (y digo TIENE y no DEBERIA puesto que esto último implica no hacer TDD correctamente, o sea, no hacer TDD).
En conclusión (este post ya se hizo muy largo), cuando se desarrolla un sistema hay muchas cosas que se deben diseñar. Desde temas relacionados al mantenimiento del software, pasando por sus características tecnológicas hasta llegar a cuestiones de usabilidad. Pero no solo esto, también hay que diseñar los procesos que se utilizarán para desarrollar y coordinar el grupo de trabajo, el ambiente en el que se trabajará, la administración del proyecto, etc. La característica esencial de maleabilidad del software obliga a los desarrolladores a prestar atención a un problema que en otras disciplinas no existe o por lo menos no es tan importante, como la posibilidad de realizar cambios al producto que está usando el usuario. Esta característica esencial hace que no podamos deslindarnos de este problema y que si o si pensemos en que nos vamos a topar con él. Una corriente de pensamiento trata de solucionarlo utilizando herramientas que terminan siendo el fin en vez del medio, intentando "adivinar" el futuro, dándole más importancia a los "artifacts" que se generan con dichas herramientas que al código mismo, mientras que otras utilizan el código como fuente de toda verdad y justicia, el fin obligado y no el "artefacto" del que toda persona de desarrollo de sistemas, que se precie como tal, trate de huir.