sábado, 24 de diciembre de 2011

Metodologías Ágiles: Adaptando Scrum

Una cosa que encontré curiosa en el desarrollo de mi PFC es que no quisimos seguir una metodología tan encorsetada y 'obsoleta' como es el caso de métrica V3, en este caso nos apeteció añadir un poco de variedad a la amplia gama de proyectos que hay presentados en esta metodología (y que por ende cuando revisas las documentaciones terminan siendo todos iguales), por ello mi co-director (@brenes) decidió que podría ser bueno una especie de 'revisión' de una metodología ágil como puede ser Scrum. Vamos a ver a grandes rasgos que es lo que hicimos:


Icebox


Para comenzar con el análisis, lo primero que hicimos fue realizar una "lista a los reyes magos", que no dejan de ser los requisitos que queremos que vaya a cumplir (por descabellados que sean) el proyecto que se va a desarrollar.

Esta lista se hace definiendo una serie de roles (actores) al estilo:


  • Usuario: Usuario de la aplicación.
  • Desarrollador: Programador que realizará el código de la aplicación.
  • Cliente: Aplicación que puede conectarse a mi proyecto.



Una vez tenemos los actores definidos, pasamos a realizar la lista de requisitos de esta forma:



  •  Como usuario, quiero poder subir mis propias producciones.
  • Como desarrollador, quiero que mi aplicación pueda repartir la carga de trabajo como si fuera una botnet.
  • Como cliente, me gustaría poder tener una API para extender funcionalidad.


Como he dicho, esto son unos ejemplos de cómo podría ser una lista de requisitos Icebox. También se puede enfocar como una tormenta de ideas en la cual se vayan añadiendo lo que se ocurra que puede encajar (más adelante se hará una criba). 

Lo ideal de los requisitos que aparezcan aquí es que se puedan realizar en un Sprint, de tal forma que si los hay que sean más duraderos, habrá que desmenuzarlos en requisitos más pequeños para que encajen.


Sprint


Un Sprint es un ciclo de trabajo incremental (una especie de desarrollo por hitos), de tal forma que siempre se tiene una versión funcional para el cliente en caso de que solicite verla. Aquí viene una de las modificaciones que adaptamos, normalmente un Sprint debe ser de corta duración pero como se está realizando el proyecto a la vez que se realiza el tercer curso de la carrera, no hay más remedio que alargarlo a casi un mes por Sprint.


Backlog


Una vez realizada la Icebox con nuestras más alocadas ideas, toca el turno de hacer una especie de lista definitiva de requisitos a implementar (que se puede ajustar después de cada Sprint), aquí lo que se hace es cribar la lista anterior (llegar a un acuerdo con el cliente) para ver qué requisitos finalmente se implementan y además, se les dará una puntuación de 1-10 entre los expertos de la materia (lenguaje) a cada uno para valorar qué debe entrar en cada Sprint. De esta forma, a lo mejor es viable incluir 2 o más requisitos en un Sprint, dejar uno sólo por ser excesivamente denso, aprovechar para redesmenuzar los requisitos, etc. 

Aquí viene otra de nuestras adaptaciones. Para valorar estos requisitos, hace falta ser un experto en la materia y poder ponderarlos en función del tiempo que va a llevar desarrollarlos (también sería idóneo que los desarrolladores fueran expertos) puesto que una mala planificación hace que el proyecto comience de forma mal y ya se sabe: lo que mal comienza, mal acaba.

Una vez hecho el Backlog, ya solo queda organizar los requisitos en Sprints y realizar reuniones por cada uno de los Sprints para ver cómo evoluciona el trabajo y poder mostrar ese desarrollo incremental.

Hasta aquí este post navideño que espero sirva también para el "DevTech Project".

miércoles, 21 de diciembre de 2011

¡Feliz Navidad!


Desde Diario de un Proyectante quiero desearles a todos los lectores una feliz navidad, unas felices fiestas y que disfruten de las fiestas que tienen por venir estos días pero ¡ojo! con cuidado que no quiero perder a ningún lector por algún exceso :)

martes, 20 de diciembre de 2011

Haciendo aplicaciones parametrizables (Properties+YAML)

Tras casi una semana sin publicar nada, toca hacer un post interlinguístico que va a tocar los palos de Java y de Ruby, es más, vamos a ver como podemos hacer aplicaciones configurables en ambos lenguajes.


¿Por qué tener aplicaciones configurables?

Es bastante común tener aplicaciones configurables que nos permitan modificar parámetros de la misma 'en caliente/on the fly' sin tener que recompilar todo el código. No es de recibo tener que recompilar toda una aplicación y parar todo un sistema en producción única y exclusivamente por el hecho de modificar un valor, como puede ser por ejemplo el IVA que se aplica actualmente o la base de datos que estamos usando (ahí habría que preveer otras cosas pero podría hacerse en caliente también).


Properties

A ver si os gusta la solución que os propongo. Introducir todos estos parámetros hard-coded (que están grabados a fuego en la aplicación) y sacarlos para un fichero que más o menos podemos considerar estándar y del que los recogeremos y podremos modificarlos a nuestro antojo.
Para hacer esto, existen en Java unos ficheros que se llaman properties y que el propio lenguaje tiene unas funciones para recoger esta información de ellos y utilizarla.
Éstos ficheros lo único que contienen dentro es una línea por cada campo en forma de pares clave,valor. En el post referido a Log4J definimos un archivo Properties para la configuración de los loggers.

Definición de un archivo Properties:

config.properties

#iva aplicable
IVA=18
#descuento del producto
descuento.producto=2

Uso del archivo:


He creado una aplicación en Eclipse muy sencilla que usa un properties para almacenar el descuento de un producto y el iva que hay en el momento.

Proyecto de Eclipse

Como podemos comprobar en el ejemplo, podríamos cambiar los valores del properties mientras se está ejecutando la aplicación puesto que se carga el fichero cada vez que hacemos una llamada al Helper.

YAML

En el caso de Ruby, existe algo parecido a estos properties, es el lenguaje YAML (YAML Ain't Another Markup Language) y los ficheros .yml donde también definiremos estos pares clave,valor pero además nos permitirán añadir jerarquías que de cara a organizar información que nos vendrá de lujo debido a la facilidad que tienen estos ficheros para crecer.

Definición de un archivo YAML:

config.yml

#iva aplicable
producto:
iva: 18
#descuento del producto
descuento: 2

Uso del archivo:

Para usar el archivo yml, he hecho una mini aplicación (igual que la de Java) donde se ve el uso del yml.

Proyecto en Ruby

Podría ser interesante para aquél que no sepa nada de Ruby, para perderle el miedo que mirara un poco el código y viera que es bastante sencillo.


Otros usos

Como viene siendo habitual en el blog, los ejemplos que se presentan intentan ser lo más sencillos posible para que todo el mundo pueda entenderlo y hacer que le pique el gusanillo a cada uno. En una aplicación un poco más seria, el uso de estos properties estaría relegado a definir en ellos las bases de datos (ip del servidor, usuario, contraseña, base de datos, consultas, ...) , configuración de un servidor jboss, el espacio de nombres de Java JNDI ...

Con esto finaliza el artículo relativo a parametrizar aplicaciones, cabe destacar que YAML no sólo se utiliza para parametrizar aplicaciones (en Ruby mayormente sí) y es multilenguaje. En la próxima entrega espero poder hablar sobre pruebas unitarias y concretamente de JUnit y el módulo Test de Ruby.

lunes, 12 de diciembre de 2011

Log4J, aprendiendo a hacer trazas

Comenzamos esta andadura 2.0 con Java, para calentar motores aprenderemos a utilizar una herramienta muy útil que dará un valor añadido a nuestras aplicaciones. Log4J (Apache, Log for Java, http://logging.apache.org/log4j/1.2/) es una forma fácil de tener un sistema de logging que nos permitirá "controlar" y monitorizar nuestras aplicaciones de forma transparente al usuario y sobretodo de una forma mucho más elegante que los típicos System.out.println de marras que son muy sencillos de insertar pero siempre podemos caer en el error de que se nos quede alguno sin borrar de nuestro código y eso da bastante mala imagen de cara a por ejemplo entregar una práctica (los mensajes aparecerán por consola) o presentar un trabajo más profesional.

Para todo lo relacionado con Java que aparezca en este post siempre se utilizará Eclipse como IDE debido a que es el más utilizado y gratuito, el proceso para utilizar otros (NetBeans por ejemplo) debería de ser análogo.


Obteniendo el JAR

Antes de nada debemos de ir a este enlace y descargarnos el siguiente zip que contiene el jar:


en este enlace, pulsaremos sobre la versión HTTP y se nos descargará. Una vez lo tengamos en nuestro poder, descomprimiremos únicamente el archivo log4j-1.2.16.jar que es el que tiene la funcionalidad de Log4J.


Configurando el proyecto

Ahora abriremos Eclipse, y crearemos un nuevo proyecto (File->New..->Java Proyect) , para este caso le llamaremos PruebaLog4J (por ejemplo). Una vez tengamos creado nuestro proyecto, añadiremos una carpeta "lib"(New->Folder) que dependerá del proyecto y en la cual pegaremos (o descomprimiremos) el jar antes mencionado. Con el jar ya descomprimido en la carpeta "lib", haremos click derecho sobre el propio jar y en el ítem "Build Path" presionaremos sobre "Add to Build Path". Automáticamente se añadirá a nuestro path y podremos utilizarlo en nuestras clases.

Estructura final del proyecto



Creando nuestra clase con Log4J

En este punto vamos a crear una clase donde probaremos los diferentes niveles de log que nos proporciona Log4J. Comenzaremos creando un paquete "test" (nunca utilizar default package) donde introduciremos una clase de prueba, por ejemplo PruebaLog4J y seleccionamos que nos genere el main también para ahorrarnos un poco en código.

Ya tenemos la clase sobre la cual hacer logging, para utilizar Log4J necesitaremos crear una instancia en todas las clases donde vayamos a usarla de la siguiente forma: 



Log4J por defecto utilizará una especie de Singleton (algún día escribiré sobre patrones) que se creará solo una vez y te dará la instancia cuando se necesite. Al método getLogger, le pasaremos siempre el nombre de la clase en la que estemos .class para que nos "personalice" los mensajes de log que nos mostrará.

Poseemos una variable logger, ¡usémosla!

Vamos a comenzar con lo básico, dentro del método main introduzcamos esto:



Con la sentencia de encima, conseguimos meter ese mensaje entrecomillado en nuestro log. 

Ahora toca hacerlo funcionar...

Si intentamos ejecutar lo que hemos hecho hasta ahora, nos mostrará un error porque falta configurar cómo queremos que Log4J nos grabe los logs.


Configurando Log4J

Hay 2 formas de configurarlo, una más básica y que no quiero ver aquí porque nos interesa más entrar en cómo hacer una configuración más a medida y que cada uno la prepare a su gusto.

Para configurarlo, tenemos que crear un archivo log4j.properties (New->File) dentro de "src" para que la biblioteca lo reconozca por defecto y dentro introduciremos el siguiente texto:

# Niveles de Log
log4j.rootLogger=trace, stdout, R


# Configuracion del Appender de la consola
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

# Appender del fichero
log4j.appender.R=org.apache.log4j.RollingFileAppender
# Path and file name to store the log file.
log4j.appender.R.File=./logs/testlog4j.log
log4j.appender.R.MaxFileSize=500KB
# Manten solo un fichero
log4j.appender.R.MaxBackupIndex=1
# Plantilla del fichero
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d - %c - %p - %m%n

Lo seguido de # son comentarios.

Vamos a intentar entender un poco qué definimos en estas líneas.
A grosso modo, un fichero .properties es un fichero de configuración que se basa en definir líneas de tipo clave=valor.

La primera línea útil que nos encontramos es la siguiente:

log4j.rootLogger=trace, stdout, R

Aquí estamos definiendo el log "maestro", que hará logging sobre todas las clases, le estamos indicando el nivel traza, por salida estándar y que lo llamaremos R.
Cada vez que veamos la R en el fichero, estamos haciendo referencia a este log que hemos definido aquí.

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

Definimos un appender para la consola.


log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

Definimos que layout (estilo) llevará nuestro log y debajo definiremos el patrón que queramos que siga.

log4j.appender.R=org.apache.log4j.RollingFileAppender

Definimos otro appender con nuestro ROOT, queremos que sea un RollingFileAppender, eso quiere decir que queremos que nos cree un fichero de texto con el log (opción fundamental de un log).


log4j.appender.R.File=./logs/testlog4j.log
log4j.appender.R.MaxFileSize=500KB
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d - %c - %p - %m%n

Aquí definimos lo relacionado con el log que hemos definido como ROOT, la ruta que tendrá el archivo (lo ideal es mantener esta estructura), el tamaño máximo que tendrá el archivo, los backups que quieres tener del fichero, qué layout seguirá y qué patrón seguirá.

Podemos añadir tantos appenders como queramos y para que salgan por diferentes archivos (esto sería lo ideal para tener un control total de nuestro programa, pero no es realmente necesario).

Con todo el fichero properties definido (y espero que más o menos entendido), ya podemos ejecutar nuestra aplicación, y así podemos ver los resultados.

Veremos por consola un mensaje del tipo:


y en la carpeta logs aparecerá el fichero pruebalog4j.log :




Ya tenemos nuestro log funcionando. Cada mensaje que queramos poner en nuestra aplicación, tendremos que hacer una sentencia como la anterior del tipo:

logger.info("Otro mensaje para el log");

Recuerden que en cada clase hay que obtener el logger para usarlo.


Niveles de Log

Ahora que ya sabemos como hacer nuestros logs, pasemos a ver qué es esto de los niveles de logging.

Existen 5 niveles en la jerarquía de logging que son de menor a mayor dureza: DEBUG, INFO, WARN, ERROR y FATAL.

DEBUG: Usaremos este nivel cuando queramos ver por dónde va la traza, así tendremos un control exhaustivo de nuestros desarrollos.

INFO: Aquí podemos definir información que puede ser útil del funcionamiento del programa, como por ejemplo decir que se están tomando correctamente unos parámetros.

WARN: Utilizaremos este nivel para mostrar un funcionamiento anómalo de nuestra aplicación pero que no afectará al funcionamiento de la misma.

ERROR: Utilizaremos este para decir que ha ocurrido un error.

FATAL: Este es el nivel superior de la jerarquía y con él definiremos un error fatal de la aplicación que llevará a la finalización inmediata de la misma.

Que estos niveles siguen una jerarquía quiere decir que si definimos un log con nivel DEBUG se mostrarán todos los mensajes que definamos, desde los logger.debug("loquesea"); hasta los logger.fatal("estovamal");
Si por el contrario definimos un nivel FATAL, solo aparecerán los logger.fatal("estorompió");

Así mismo, esto que acabo de escribir sirve para orientarse de cómo escribir diferentes niveles de log en nuestra aplicación.


Finalizando

Ya hemos terminado, sólo queda que cada uno mire los patrones de cómo configurar los layouts y esa no es tarea fácil pero seguro que será muy reconfortante una vez se tiene definido como uno quiere puesto que hay infinidad de opciones. Aquí estan todas.

Al principio comenté que a diferencia de los System.out.println el log podía quitarse para no dejar rastro en la ejecución, aquí entra otra vez el fichero properties y los niveles de la jerarquía. Lo ideal es poner un nivel INFO cuando se pasa a producción y tan sólo en el fichero, quitaríamos el appender de la consola. El código permanecerá en nuestros ficheros que una vez haya que mantener ese código, solo tendremos que reestablecer el nivel DEBUG.

Pues hasta aquí el primer post-tutorial de cómo conseguir definir nuestro propio sistema de Logging, espero que os haya servido de ayuda y ojalá alguien me comente sus experiencias y qué patrones ha seguido en sus configuraciones. Para ello, tenéis a vuestra disposición mi cuenta de Twitter @Minikisto y los comentarios de este mismo post. En la próxima entrega, probablemente nos centremos en JUnit y unas nociones básicas de estructuración de la información de un proyecto.


sábado, 10 de diciembre de 2011

Presentación



¡Hola! primero déjenme presentarme. Soy Daniel Machado Fernández y estoy cursando tercero en la Ingeniería Técnica en Informática en la Universidad de Oviedo a la par que estoy realizando el Proyecto Fin de Carrera (PFC).

Bueno, ya me conocen, déjenme presentarles ahora el blog. Diario de un Proyectante pretende ser un cajón de sastre donde intentaré comentarles qué problemas me voy encontrando a lo largo de la realización de mi PFC, pero no solo eso, también me gustaría escribir sobre buenas prácticas a la hora de desarrollar software (sobretodo a utilizar las herramientas adecuadas). No quiero limitarlo a estos 2 puntos (que ya sería bastante), me gustaría poder escribir sobre lo que me apeteciera, sobretodo cosas que fueran útiles, que no se enseñan en la carrera de informática o al menos que no se enseñan en ninguna asignatura obligatoria/troncal y que si se quieren aprender se tienen que hacer por cuenta propia.

Quiero que quede claro que en este blog se va a hablar sobre Ruby y Java dado que este último es el lenguaje base que se utiliza en mi Universidad y Ruby es el lenguaje que he escogido para realizar mi PFC por lo que son los lenguajes de los que más puedo hablar.

No quiero que piensen que soy un experto Java ni mucho menos, ya he dicho que soy estudiante por lo que probablemente todo lo que les cuente ya lo conozcan pero eso no quiere decir que estas cosas no haya tenido que buscarlas en algún momento de la carrera, que me han sido útiles y que suelo utilizar en mi día a día.

Por último para los que tengan curiosidad, voy a dejarles en este mismo post unos enlaces a tutoriales que he hecho en algún momento de mi vida sobre Java y Ruby que me han sido realmente útiles.

Java: Aprende Java como si estuvieras en Primero, de Tecnum
Ruby: Why's (poignant) Guide to Ruby (Inglés)
           Learn Ruby (Inglés)
           Guía del usuario de Ruby

Si quieren contactarme, pueden hacerlo en Twitter .