martes, diciembre 12, 2006

El Programa

¡Cuántas veces nos dejamos guiar por el programa que hemos construido desde nuestra educación, nuestra sociedad, nuestra manera de ser o nuestras costumbres! Y los "nuestros" de antes no son malos, simplemente son. Pero en ocasiones, merece la pena, levantar el pie del acelerador, quizá incluso apretar un poco el pedal del freno y mirar mejor por dónde vamos. O mejor, mirar mejor cómo nos conducimos. Y veremos que muchas veces no es que las señales estén equivocadas, o que lo estén las normas... Lo que parece que está equivocado es el camino que estamos siguiendo...

miércoles, septiembre 06, 2006

Estética

Otro pensamiento medio cocinado.

Cada vez creo más en la importancia de la estética en la informática. No me estoy refiriendo (únicamente) a la interfaz del usuario, la característica más visible del software, o al menos la de público más amplio. Me estoy refiriendo sobre todo a la estructura interna, la arquitectura, el uso de patrones, el estilo del código, los nombres de las variables, los diagramas de bases de datos, los diagramas de clases, la claridad de la descripción en los casos de uso...

En ese sentido, creo que otras ingenierías artísticas (o artes ingenieriles), como por ejemplo la arquitectura, tienen mucho que ver con la informática. Conceptos como los de simetría, repetición, coherencia (integridad conceptual, The Mythical Man-Month, Brooks), etc. los veo fácilmente aplicables a la ingeniería del software.

Creo además que incluso la literatura nos puede ayudar (Knuth). El desarrollo de software tiene que ver mucho con escribir un buen libro, o crear un edificio.

Una pequeña nota. Cuando antes hablé de repetición, no me refería al modelo de reusabilidad de código que denomino copypaste (es decir, si este código me vale, lo copio, y lo pego en mi proyecto con pequeñas modificaciones), sino más bien a la inteligibilidad que otorga que lo que es conceptualmente igual se refleje de la misma manera en el código (Añadir y Agregar son sinónimos, pero en un código estético sería imperdonable utilizar en unos sitios un identificador, y en otros sitios el otro.

Me gusta la idea, creo que reincidiré en ella.

viernes, abril 21, 2006

Formación rentable

Últimamente estoy muy influenciado por ciertos pensamientos de índole económica. Los culpables son Barry Boehm, y su libro "Software Engineering Economics", Kent Beck con su "Extreme Programming Explained" y algunos compañeros del trabajo, que justifican sus decisiones técnicas y no técnicas en términos de inversión, rentabilidad, retorno, valor, ingreso, gasto o beneficio.

Como siempre a la hora de tomar una decisión, tener el máximo de información es bueno, y tener máximo de información de un sólo aspecto es malo. Así que es lógico tener en consideración tanto los aspectos económicos como los técnicos, los psicológicos, los éticos o los sociológicos, por poner algunos ejemplos. Pero me estoy desviando del mensaje original.

Parafraseando la presentación de los eXpedientes, "el conocimiento está ahí fuera", y es enorme (entiende uno la importante labor de los bibliotecónomos y los archiveros). La pregunta es ¿qué conocimiento me interesa aprender? que es una pregunta similar a la que se hace un eNavegante mientras explora la Red: "De todas las páginas que puedo ver, ¿cuáles me interesan más?".

Pues nada, aplicamos conceptos económicos. Aquellos que puedes aprender una vez (inversión) y aplicar muchas veces (retorno). Además ese conocimiento debe ser útil para los demás, no necesariamente para tí, aunque deberías poder disfrutar aprendiendo de él (el aprendizaje es más eficaz si te gusta lo que estudias, eso lo sabemos todos). Para que puedas aprenderlo una vez y aplicarlo muchas (read once, write many ;-), el conocimeinto no debe "degradarse" con el tiempo, es decir, debe ser un conocimiento que no dependa de aspectos pasajeros (por ejemplo, enfoca en principios universales de diseño software, en vez de en la última versión del HackerMasterDeveloperEnvironment Professional Edition, que tiene muchas probabilidades de tener una próxima versión en la que cambia casi todo). Además, con el tiempo, aprender cuesta más, y es lógico que pasados unos cuantos años, alguien con más tiempo y habilidad que tú, con el cerebro más avispado te adelante con la última tecnología... Empleate en los fundamentos, en los conceptos, en los principios, en la base... Y mejora tu habilidad para aplicar esos conocimientos.

lunes, marzo 06, 2006

Pruebas

Hoy he probado a probar. He instalado la última versión de NUnit (la 2.2.7) y he decidido probar con uno de nuestros proyectos. La experiencia ha sido intensa para ser la primera vez que intentaba probar un sistema real ya construido (algunos me dirán, con razón, que eso debería haberlo pensado antes, pero equivocarse es una buena manera de aprender).

Bueno, pues sólo por haberlo intentado, ya me he encontrado con ciertas dificultades, que me han servido para reflexionar un poco y llegar a algunas conclusiones.

Diseña para probar
La primera es que el sistema tiene que estar diseñado para ser probado. Es muy difícil probar un sistema que no está pensando con el proceso de pruebas en mente. Los criterios de acoplamiento y cohesión son en mi opinión de especial importancia, y tener este proceso presente favorece su aplicación. En particular, disponer de clases poco acopladas facilita el diseño de los casos de prueba al no ser necesario simular demasiadas de esas clases. Para ilustrar esta reflexión y las siguientes, voy a describir el caso particular que me llevó a ellas.

El sistema es una aplicación web con arquitectura en tres capas (presentación, lógica y datos) con sus funciones habituales. Ciertas operaciones usadas habitualmente por varias clases de la capa de presentación fueron recogidas en varios métodos de clase. Una de estas funciones determina si la IP del navegador pertenece a la red local o no. Su signatura tal y como estaba programada en un principio es la siguiente (Visual Basic.NET):
Public Shared Function EsIPInterna() As Boolean
:
El principal problema era que ¡no recibía ninguna dirección IP! Examinándo el código, comprobe que la dirección IP se obtenía de la cabecera HTTP enviada por el navegador:
:
Dim direccionIp As String = Request.ServerVariables("HOST_ADDRESS") 'O algo así
:
La función dependía internamente de un objeto disponible en el contexto del Internet Information Server de Microsoft. Las pruebas deben ejecutarse en un entorno que desde luego no es el IIS y en el que por tanto no tenemos acceso al objeto Request. Para salvar este primer inconveniente, modifiqué la signatura de la función de esta forma:
Public Shared Function EsIPInterna(ByVal ip As String) As Boolean
:
Y a continuación, cree una nueva función que permitiría no modificar el resto del código:
Public Shared Function EsIPInterna() As Boolean
   Return EsIPInterna(Request.ServerVariables("..."))
End Function
La primera función me permitiría pasar varios argumentos a la función y poder probarla. Lo dicho, las pruebas tienen que estar siempre presentes en el proceso de diseño y construcción.

Prueba la reusabilidad
Como segunda reflexión, he percibido que el proceso de pruebas puede favorecer la reusabilidad. En efecto, el obligar a probar una u otra función con un juego de datos que cubra por ejemplo el criterio de pruebas de caja negra obliga a exponer aquellos parámetros que sean necesarios para ejercitar el código. Esta exposición En otro caso, el sistema debe cambiar para adecuar las pruebas. Mejor hacerlo entonces desde el principio. Lo hemos visto en el caso anterior. La función EsIPInterna que recibe el parámetro podría ser reusada en otros proyectos.

Prueba a desacoplar
Probar un sistema casi obliga a disminuir todo lo posible el acoplamiento. La necesidad de probar las clases por separado fuerza en cierta forma a diseñarlas de manera que dependan lo menos posible unas de otras. Para que el proceso de pruebas sea efectivo, es necesario en todo caso que dicha dependencia sea explícita (por ejemplo, en la forma de parámetros en la construcción). Además, se refuerza la esencia colaborativa del diseño orientado a objetos.

Castillos en el aire
Las pruebas son especialmente difíciles de diseñar en aquellos casos en los que el código depende de alguna plataforma tecnológica, precisamente porque es difícil simular dicha plataforma (salvo que, una vez más, el sistema esté diseñado de forma que lo permita). Ejemplos de dichas plataformas son el servidor web (un IIS en mi caso), o un middleware o monitor transaccional (COM+ en mi caso). En el ejemplo esta reflexión se hace evidente.

Conclusiones
Como resumen, probar te permite orientar tu diseño para permitirte precísamente poder probarlo, aumentar su reusabilidad, disminuir su acoplamiento y abstraer lo más posible tu código de la plataforma tecnológica que estés usando en cada momento. No se le puede pedir más a una función... Veremos a ver qué aprendo de las próximas cientos de miles...