Este artículo es una traducción del documento Memoization in Groovy, escrito por Brendon Anderson en el blog de Object Partners. Deseo mostrar mi más sincero agradecimiento tanto al autor por escribir un artículo tan práctico y sencillo como a Ehren J. Seim por responder afirmativamente a mi petición para realizar la traducción del documento a español, y así difundir el conocimiento a la comunidad hispana de Groovy.

This article is a translation of the document Memoization in Groovy, written by Brendon Anderson in Object Partners's corporate blog. I wish to express my sincere thanks to the original author for write such a practical and easy-to-read article, as well as Ehren J. Seim for accept the spanish translation request and thus spread the word to the Groovy hispanic community.

Thanks a lot guys :)

¿Qué es Memoization?

Memoization (que aunque no es directamente traducible a español representa un concepto similar a memorización) es una forma de cacheo disponible en Groovy. Según su artículo original en Wikipedia (entre otros sitios) memoization es una técnica muy útil al realizar cálculos recursivos, aunque puede ser usando en cualquier situación en la que sea necesario almacenar cálculos previos basados en una entrada específica. Es importante hacer constar que memoization debe ser usado de forma distinta a como usamos un cacheo regular (en el contexto de Spring Cache, por ejemplo). Este último generalmente implica que, o los datos expirarán eventualmente, o simplemente cambiarán en el algún momento futuro, mientras que memoization está dirigido hacia cosas que siempre van a ser verdad (en otras palabras, datos que no van a cambiar). 5! (factorial de 5) va a ser siempre 120, mientras que el resultado de una llamada a un sistema remoto para obtener información de un usuario basado en un identificador (como idUsuario) podría cambiar. Groovy proporciona memoization en closures desde la versión 1.8. La capacidad de realizar memoization directamente sobre métodos ha sido añadida recientemente, más concretamente en la versión 2.2. Mirando el código fuente vemos que memoization en métodos usa la ya citada capacidad existente en closures; básicamente, la anotación @Memoized envuelve en un closure la llamada al método donde es aplicado.

Memoization en closures

En el siguiente código se muestra un ejemplo básico de memoization en closures:

Leer artículo completo


En una aplicación ideal (quien haya visto una que me lo diga, será mi nuevo héroe) entre otras cosas no debería haber sido escrito ni un solo comentario, ya que el propio hecho de usarlos es sinónimo (¿consecuencia tal vez?) de código no legible. Algunos programadores tienden a comentar de forma natural (a veces compulsiva) gran parte de código que escriben, pero con todo el respecto hacia su trabajo la realidad es esa. Por otro lado, el propio comentario cuya supuesta misión es aclarar el código está añadiendo información (y por tanto complejidad) al documento, lo que va a provocar que su objetivo se vea, en mayor o menor medida, defenestrado.

Existen ciertas situaciones puntuales en las que, sin embargo, un comentario puede llegar a ser útil e incluso necesario:

  • Cuando los requerimientos del cliente no han sido definidos con claridad o están pendientes de análisis; también aquellos que son ajenos al ámbito del problema de negocio pero deben ser aplicados
  • Cuando es necesario realizar tratamiento de datos de forma no estándar (por ejemplo al realizar operaciones aritméticas complejas u operaciones extravagantes con cadenas de texto, cuando debemos aplicar una serie de operaciones de forma consecutiva entre las cuales y bajo ciertas condiciones algunas pueden ser opcionales, etc)
  • Cuando necesitamos expresar información relativa al desarrollo y no al problema de negocio (por ejemplo marcar tareas pendientes de realizar, informar de errores que han sido detectados pero aún no corregidos, registrar el origen de un fragmento de código que estamos reusando, etc)
  • Cuando no estamos codificando información si no comunicando información (por ejemplo al hacer referencia a un fragmento de código en un correo electrónico o en un reporte de error, cuando estamos formando personal y necesitamos aclarar conceptos que pueden resultar confusos, etc)

Tal vez los motivos citados para usar comentarios te resulten contundentes (para mí lo son) y por ello estés pensando que un mejor nombre para este artículo hubiera sido algo parecido a Usando buenos comentarios (para mí no lo es): el uso de comentarios debe reducirse a situaciones excepcionales (las cuales suelen ser marginales), su omisión te va a ayudar a escribir mejor código (ya que estarás obligado a que éste refleje una intención per se para poder ser entendido y mantenido), y su abuso te va a inducir a todo lo contrario. Por todo esto, y en caso de duda, es preferible la omisión de unos pocos comentarios útiles a la proliferación de multitud de comentarios inútiles.

Finalmente, los comentarios para la generación de Javadoc's no son omisibles (si buscabas una excusa para no escribirlos, hoy no es tu día de suerte), y no sólo es importante su uso si no también su adecuado mantenimiento.


Ya está disponible la web adaptada a dispositivos móviles, la cual es accesible a través de la misma dirección que la versión de escritorio. Para una correcta visualización de la página he realizado pruebas con multitud de configuraciones dispositivo/navegador, si aún así detectas que el renderizado no se hace de forma correcta te agradeceré que me envíes por correo electrónico una captura de pantalla y los valores antes mencionados (dispositivo y navegador). Vuestro feedback es también muy importante, por lo que os invito a que os pongáis en contacto conmigo sobre cualquier aspecto de la nueva web móvil que consideréis importante (diseño, usabilidad, etc).

Aunque la versión móvil se genera a partir de código HTML propio (ligeramente distinto al de la versión de escritorio), quiero agradecer a Ezequiel Antúnez el correo electrónico que me envió hace unos días recordándome la importancia del diseño adaptativo.


Hoy hace cuatro años que publiqué un sencillo artículo de presentación, artículo que sentaba la primera piedra de una idea que me surgió semanas antes: mi propio blog de programación. Es curioso como, tras ver publicada aquella entrada, no dejaba de preguntarme: ¿entrará alguien alguna vez aquí?. Hoy, cuatro años después y con más de 650.000 visitas y 1.600.000 páginas vistas, lo que no dejo es de sorprenderme.

Un año más gracias a todos por vuestras sugerencias, críticas, y el constante apoyo que me brindáis; por ayudarme a que esa idea, que luego fue proyecto, siga creciendo con la misma ilusión con la que empezó.


XML es el lenguaje de los Servicios Web. Cuando invocamos un servicio u obtenemos una respuesta desde el mismo, toda la información que estamos enviando/recibiendo es en formato XML. Tanto la estructura de datos de un servicio como su interface se definen con XML. XML está presente en todas partes cuando hablamos de Servicios Web.

En este segundo artículo del tutorial de Servicios Web en Java vamos a ver las bases de XML desde una perspectiva teórica, para a continuación adentrarnos en la parte práctica a través de las API's StAX y XPath.

2.1 XML: lenguaje de marcado

XML (eXtensible Markup Language, Lenguaje de Marcado Extensible) es como su nombre indica, un lenguaje de marcado: un lenguaje para codificar un documento mediante marcas (etiquetas), las cuales contienen información acerca de la estructura, contenido y/o presentación de dicho documento. HTML es otro lenguaje de marcado, aunque éste fue diseñado con la intención de presentar información (mientras que la misión de XML es la de estructurar, transportar y almacenar información).

2.2 XML: estructura y sintaxis

Un documento XML se compone como mínimo de una declaración, un elemento raíz (también llamado elemento padre) y uno o más sub-elementos (también llamados elementos hijo), que a su vez pueden anidar otros sub-elementos:



	
		DDD-1111
		Toyota
		Prius
	
	
		HHH-4444
		Audi
		A5
	

	

La primera línea es la declaración XML, y en ella se define tanto la versión de XML como la codificación que vamos a usar en el documento. En los próximos ejemplos se omitirá para simplificar el código, pero en el mundo real debes usarla siempre.

El resto del documento contiene la información en si. A la estructura de un documento XML se la llama árbol XML ya que podemos considerar el elemento padre <parking> como la raíz, cada uno de los elementos hijo <plaza> como una rama, y cada uno de los elementos hijo <matrícula>, <marca> y <modelo> como una rama que nace de la rama anterior.

Leer artículo completo


Hace ocho días publiqué el primer reto Bug Master, en el cual se introdujo un error de ámbito de variable. Hay que reconocer que la solución al reto no era muy complicada y la mayoría de vosotros es capaz de resolverlo, pero algo me dice que algunos os estáis preguntando ahora mismo: ¿qué demonios es el ámbito de variable? En este artículo lo vamos a explicar.

Definición de ámbito

El ámbito de una variable define su alcance de uso, o lo que es lo mismo, en que secciones de código una variable estará disponible. Fuera de este ámbito, una variable no podrá ser accedida (no existe).

Tipos de ámbito

En Java tenemos tres tipos de ámbito que pueden aplicar a una variable:

  • Local
  • Global
  • Estático

Veamos un fragmento de código donde aparecen los tres tipos, antes de pasar a explicar con un mínimo de detalle cada uno de ellos:

public class MiClase {
	static int variableEstatica;
	
	int variableGlobal;
	
	void miMetodo(int parametro) {
		int variableLocal;

		// parametro también es local dentro del método
	}
}
	

Variables de ámbito local

Las variables de ámbito local, o de bloque, son aquellas que sólo pueden ser accedidas desde el bloque de código en el que han sido declaradas (que no inicializadas).

Leer artículo completo


Después de semanas de duro trabajo en mi tiempo libre ya está aquí la nueva web de davidmarco.es.

A nivel técnico la web se ha escrito desde cero, usando HTML5 y JQuery en el front-end y NodeJS en el back-end. Este último es tan potente que me ha permitido incluso redirigir las antiguas direcciones PHP sin escribir una sóla linea de código en dicho lenguaje (uno de los grandes problemas que tenía que resolver cuando comencé el desarrollo y decidí usar NodeJS). En un artículo anterior publiqué algunos detalles sobre la infraestructura que soporta el back-end.

A nivel visual, sin mostrar un cambio radical de diseño, sí que se ha mejorado enormemente la presentación: un diseño más limpio, mejores tipografías, paginación en el blog para acelerar la carga y sobre todo la nueva sección Archivo, que sustituye a la antigua sección de Tutoriales: ahora puedes consultar todos los artículos publicados hasta el momento, filtrarlos por temas (etiquetas), y por supuesto consultar las traducciones y tutoriales publicados. De esta manera la navegación por los contenidos de la web es mucho más sencilla y agradable.

¡Espero que os guste la nueva web!


A las 4 de la madrugada (y después de muchas horas delante de una pantalla) todos los gatos son pardos, y es fácil cometer errores de codificación. Yo no me he librado esta noche, y he introducido en el código de la nueva web un error muy sutil, tanto que, una vez detectado, me ha costado varios minutos resolverlo (entre depuración, trazas y despliegues varios) a pesar de estar involucradas tan sólo cinco líneas de código.

Y como una de las mejores maneras de mejorar nuestras habilidades como programadores es analizando el código de otros, con esta entrada doy comienzo a los retos Bug Master.

Reto Bug Master No1: En el siguiente fragmento de código JavaScript hay un bug. ¿Puedes identificarlo, corregirlo, y dar una definición técnica de dicho error con un máximo de 5 palabras?

var archivoitemSeleccionadoClass = "";

for (var i = 0; i < resultadoEtiquetas.length; i++) {
	if ((etiquetaFiltro) && (etiquetaFiltro == resultadoEtiquetas[i].ETIQUETAS)) {
		archivoitemSeleccionadoClass = "archivoitemSeleccionado";
	} 
        		
	etiquetas = etiquetas + "<li class='archivoitem " + archivoitemSeleccionadoClass + "'><a href='/archivo/" + resultadoEtiquetas[i].ETIQUETAS + "'>#" + resultadoEtiquetas[i].ETIQUETAS + "</a><li>";
}

Podéis responder al reto en la entrada correspondiente de mi perfil de Google+. Quien obtenga más votos (+1) en su comentario durante los próximos 8 días (no tiene porqué ser el primero en contestar) será nuestro primer Bug Master. Si alguien comenta pero no vota nadie, yo elegiré un ganador. Si no comenta nadie, yo seré el Bug Master (y por supuesto me llevaré toda la gloria).

Cuando acabe el plazo de este reto escribiré un artículo mostrando el porqué de este bug y como evitarlo cuando escribamos código.

Leer artículo completo


Con este artículo da comienzo el tutorial de introducción a los Servicios Web en Java. Los primeros artículos, que serán casi netamente teóricos, nos van a proporcionar la base de conocimiento necesaria para poder afrontar la cantidad brutal de especificaciones y herramientas que forman parte de, o están relacionadas con, los Servicios Web en Java. Serán estas especificaciones y herramientas las que darán forma a los artículos más técnicos, y en los que encontrarás multitud de ejemplos en código.

Muchos de los artículos técnicos serán (siempre que sea posible) autocontenidos, de manera que la tecnología que se trate en él pueda ser aplicada directamente sin tener una base previa y/o adicional. Sin embargo, todos en conjunto te darán una visión más amplia de los Servicios Web en Java, y te ayudarán a comprenderlos mejor (además de mostrarte otras posibilidades para resolver un mismo problema). El orden de publicación será (siempre que sea posible, again) el adecuado para que la curva de aprendizaje sea asequible.

En este primer artículo vamos a hacer una aproximación a la Arquitectura Orientada a Servicios y a su ingrediente esencial: el servicio.

1.1 Definiendo un servicio

Un servicio es un componente de software que, dependiendo de su tipo, puede tener una función mayor o menor. Sin embargo existen ciertas cualidades que suele cumplir todo servicio:

  • Está definido por una interface
  • Está disponible a través de una red
  • Opera sobre objetos de negocio
  • Puede ser decorado con funcionalidad adicional
  • Es reusable

Veamos una por una las cualidades anteriores.

Leer artículo completo


Estoy terminando de afinar la nueva versión de davidmarco.es, desarrollada en lenguaje HTML5, la cual ya podéis visitar. Algunas secciones (Tutoriales y Sobre mí) todavía no son accesibles, aunque el blog es totalmente funcional.

Debido a que los artículos de la web original están horriblemente formateados con HTML (en lugar de CSS), reformatearlos se está convirtiendo en una tarea que requiere tiempo, paciencia y mucho cuidado. Estimo que en dos semanas habré terminado, aunque los artículos más nuevos ya disponen del nuevo formato (los voy actualizando sistemáticamente en el instante en que termino de editarlos). En ese momento apuntaré el dominio a la nueva web y sacaremos las copas para brindar.

A nivel técnico la nueva web está funcionando sobre el PaaS de Openshift, el cual:

  • Se crea y configura en cuestión de minutos
  • Se integra a la perfección con mi entorno de desarrollo (un único click para desplegar la aplicación)
  • Permite una gestión más detallada a través de shell
  • Soporta de forma nativa tecnologías que mi proveedor de hosting actual (Arsys) no me ofrece (Node.js, Git...)
  • Es muy rápido y estable (tanto o más que mi solución de pago actual)
  • Tiene coste cero al nivel de prestaciones que necesito. En caso de necesitar más recursos, es totalmente escalable
  • Es un proyecto de RedHat, lo cual me inspira mucha confianza

No dudéis en poneros en contacto conmigo si necesitáis ayuda o información sobre el PaaS de OpenShift (si es un problema técnico o de puesta en marcha os recomiendo que visitéis la página de soporte y los QuickStarts, respectivamente). Así mismo, todo el feedback que me enviéis sobre la nueva web será muy bien recibido, ya sea a nivel técnico, funcional o estético (al fin y al cabo los usuarios de la web sois vosotros). Si en algún momento el servicio no está disponible volved a probar pasados unos instantes, ya que probablemente esté realizando un despliegue (el cual requiere entre uno y dos minutos).

Actualización: la nueva web ya está online.