Agile Manifesto. Camino del AOS

Ayer hubo un evento de introducción a las metodologías ágiles Camino del AOS, donde estuve explicando el manifiesto ágil y sus principios.

Os dejo la presentación:

La verdad que hubo una asistencia más que aceptable para un evento un lunes, además de ver un número de no-desarrolladores interesante :)

Y ya puestos, aprovecho a invitar a cualquier persona a que se venga este fin de semana al AOS 2012 para aprender o profundizar en temas relacionados con las metodologías ágiles. Seguro que nos lo pasamos bien :)

Como se hizo elDisparate.de, en BetaBeers Zaragoza

Este viernes estuvimos Mamen Pradel y yo hablando en el 2º BetaBeers Zaragoza. Presentamos como hicimos elDisparate.de durante el desafío AbreDatos 2011.

En la presentación explicamos rápidamente el proyecto, los principales retos y problemas que surgieron durante el fin de semana y dimos algunas pinceladas de como cada miembro del equipo ejecutó su trabajo.

Sólo teníamos 15 minutos, pero creo que fue suficiente para poder hacerse una idea de qué hicimos en márketing, diseño, video y programación; y las limitaciones del resultado no haber tenido datos abiertos.

En fin, os dejo aquí el clásico video:

Y un post del año pasado en el que expliqué un poco lo que fue la parte de obtención de datos y programación.

¿Cuánto vale una web?

De vez en cuando algún conocido-amigo que sabe que me dedico a algo que tiene que ver con esto del interné me hace esta temida pregunta... Está bien que gente de fuera del sector se empiece a interesar en introducirse e invertir parte de sus ahorros, pero algo mal hemos hecho como sector para que se crea que es barato montar algo en internet.

Tengamos en cuenta que, sobre todo para alguien que no conozca el sector, tendrá que contratar cosas relacionadas con: Diseño, programación, contenido y marketing. Y esperemos que conozca o, al menos, tenga contactos en el nicho al que se pretende dirigir.

Entonces, ¿Cuánto vale una web? Mi respuesta inicial, suele ser algo del estilo:

  • Ufff!!
  • Eeeeh...
  • Pfff!!
  • Mmmmm...

Y termino con algo como "A saber, si quieres algo en plan presencial y serio, desde 1000 y pico o 2000 euros. Si es más, hasta lo que tengas. Depende". A veces la gente se asusta.

Lo mismo me pasa recibiendo algunas peticiones de presupuesto por email, que se limitan a "quiero una web", "un ecommerce", "una red social"... Pareciendo esperar que les mandes una propuesta detallada, hasta el último euro.
O por otro lado a gente pidiendo que les hagas un clon de alguna killer application; usando wordpress, joomla, ruby on rails... sin tener ni idea de lo que supone, y por 3000 euros, por supuesto. Y lo preocupante es que a veces llegan ese tipo de peticiones de gente que, aparentemente, llevan un tiempo moviéndose en eventos relacionados con el sector.

Seamos serios, también en internet si quieres algo que se parezca a un negocio, te puede costar lo mismo que montar un bar. Y sí, como a los bares también les pasa, si no entra nadie a consumir, tendrás que cerrar.

- ¿Y cuanto cuesta montar un bar?
- Depende.

¿Cuánto vale una web?

En fin, que si tu intención NO es hacer algo serio donde pueda ayudarte programando y/o colaborando en la conceptualización del producto, ahorremos nuestro tiempo y nos vemos en los bares.

Reutilizar un custom validator en Grails

En estos momentos ando colaborando con Sergio del Amo en un producto propio para su empresa Softamo, un producto que estamos desarrollando con Grails.

El tema es que teníamos un puñado de clases de dominio que están relacionadas con un propietario, una clase User. Cada instancia de esa clase de dominio debía tener un nombre único por propietario, por lo que debíamos usar un custom validator. Al final, tras varias refactorizaciones llegamos a una solución que creo que quedó bastante elegante.

Las clases de dominio heredan de una clase padre con varios métodos comunes, además de una clausura estática que contiene la lógica de la validación uniqueByUser, que es lo que nos interesa para esto.

static uniqueByUser = { value, object ->
   propertyName = propertyName[0].toUpperCase() + propertyName[1..propertyName.size()-1]
   def methodName = "findByUserAnd${propertyName}"
   def obj = object.class."$methodName"(object.user, value)
   if(obj && (obj.id != object.id)) {
     return 'unique'
   }
}

Vale, por si no queda del todo claro, intento detallar que hace el código:

  • propertyName, es el nombre de la propiedad/atributo sobre la que se ejecutará la validación, variable que está implícita en la clausura.
  • propertyName[0].toUpperCase() + propertyName[1..propertyName.size()-1], ponemos en mayúscula el primer carácter del nombre del atributo (por ejemplo "name" pasa a "Name").
  • def methodName = "findByUserAnd${propertyName}", ponemos el método al que vamos a llamar para saber si ya existe un valor con mismo usuario y atributo buscado (por ej: findByUserAndName).
  • def obj = object.class."$methodName"(object.user, value), ejecutamos ese findBy* estático sobre la clase del objeto instanciado que se está validando, pasándole el usuario relacionado y el valor del atributo (algo que podría ser equivalente por ejemplo a Drink.findByUserAndName(drink.user, "vodka")).
  • if(obj && (obj.id != object.id)), comprobamos que si se devuelve un valor, no sea el mismo que la instancia del actual.
  • return 'unique', en este caso devolvemos el código de mensaje de validación como unique, por lo que aprovecharemos los mismos mensajes i18n del unique estándar de grails.

Entonces, en nuestras clases de domino que hereden de ahí, para el atributo donde queramos utilizar ese constraint simplemente deberemos indicar validator: uniqueByUser. Algo como:

static constraints = {
   name blank: false, validator: uniqueByUser
   description blank: false
}

Lo único que no contempla ahora mismo esta solución es tener más de un custom validator, principalmente porque no nos ha hecho falta. Si lo llegamos a necesitar, veremos como lo hacemos, claro :P.

Mejoras y propuestas bienvenidas.

ACTUALIZACIÓN: Mejor que darle tantas vueltas como hicimos nosotros, es utilizar el soporte multi-column de la constraint unique (Nota mental: No dar por supuestas según que cosas, e ir a verlo a la documentación). Gracias al comentario de @jneira.

Open Space. Código como Expresión.

Este fin de semana estuve en Valencia en el open space convocado por agilismo.es, que llevaba por nombre Código como Expresión. La verdad que hacía tiempo que me apetecía asistir a un open space exclusivo sobre código, además de volver a visitar Valencia, conocer un poco la escena de desarrolladores y ver las oficinas de beCode (aún tengo pendiente pasar unos días con ellos).

Finalmente fui desde Zaragoza con Miguel Ángel Baztan y Fernando Pérez, 2 de los habituales del grupo Agile Aragón. En el evento también había gente llegada desde Castellón, Madrid, Segovia... incluso Pepe que se pegó una auténtica paliza de viajes desde Santiago de Compostela. Entre unos y otros, estuvimos algo más de 30 personas.

A niveles generales, me gustó bastante el evento, salvo un par de detalles/sensaciones que tuve durante algunos debates. He intentado hacer un pequeño resumen de cada sesión, pero por el formato del evento y mi torpeza, no he sido capaz.

Tablón. Open Space Código como Expresión

¿De qué se habló?, en las conversaciones y debates que estuve yo:

  • De la (poca) expresividad de las APIs REST, aunque para exponer e integrar sistemas diferentes, hasta el momento, es habitualmente la mejor alternativa.
  • Del spaghetti code relacionado con el uso de javascript asíncrono y algunas buenas prácticas para mejorar ese código.
  • De lenguajes y paradigmas de programación (orientado a objetos, funcional, procedimental); y como conocer varias opciones nos hacen enfocar soluciones desde más puntos de vista.
  • De la nomenclatura y expresividad en los tests. De frameworks de testing tipo BDD para diferentes lenguajes.
  • De identación y comentarios en el código.
  • De herramientas: IDEs, editores, tableros tipo kanban, software para hacer pair programming...

Os dejo las fotos que ha publicado Emma del evento.