Buscar en este blog....

viernes, 22 de abril de 2011

Programación Orientada a Aspectos. Implementando un Aspecto. (Parte 3)

En la parte 2 planteamos una situación utópica: que una clase realizara algo sin indicarle que lo hiciera. Bueno, sí, eso es utópico. Pero, podemos pensar en otra "entidad" que se encargue de realizar esa tarea (en nuestro caso es registrar un movimiento) detectando el momento preciso en el que debe realizarla. Es decir, tener "algo" que sepa cuando registrar un movimiento, pero que ese "algo" no tenga nada que ver con la clase Cuenta. Ese algo, es lo que llamamos aspecto. Un aspecto, entonces, es algo que entrecruza una o más clases. Dicho de otra forma, un aspecto es un concepto que ofrece funcionalidad transversal a los objetos del negocio.

Imaginémoslo como algo que vigila un programa a medida que este se ejecuta; y a partir de ciertas acciones que se producen en el programa, este algo realiza acciones propias de él. Llamemos a este algo "aspecto". Podemos decirle a un aspecto, que cuando se termine de ejecutar cualquier método que comience con la palabra "hacer" realice un registro de movimiento. La clase Cuenta de nuestro ejemplo, no se enteraría jamás de la existencia de este aspecto, pero este aspecto está atento a las ejecuciones hacerAlgo...() de esa clase.

Vamos a definir rápidamente este aspecto para poder visualizar mejor lo que estamos tratando de decir. Para poder escribir un aspecto y compilar el programa con este aspecto, es necesario tener instalado el plugin de AspectJ en el editor de Java que estemos usando, o poder compilar configurando el editor. Bueno, pasemos a definir el aspecto de una vez. Agregamos un nuevo archivo con extensión .aj (por "AspectJ") al proyecto:

public aspect RegistroDeMovimientos {

after():execution (public * hacer*(..)) {
Date hora = new Date();
SimpleDateFormat formatoDeFecha = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss");
System.out.println("Movimiento realizado a las " + formatoDeFecha.format(hora)) ;
}
}


Observemos este código. Lo primero que vemos, es la declaración del aspecto bajo el nombre de RegistroDeMovimientos. Por ende, al igual que las clases de Java, el archivo del aspecto debe llamarse RegistroDeMovimientos.aj. Si seguimos vemos la linea que dice:

after():execution (public * hacer*(..)) {


Esta línea es clave para definir unos conceptos que explicaré más adelante. Pero por el momento, analizaremos de manera simple qué significa. Si tuviera que decirlo en lenguaje informal, la describiría asi: "Después de la ejecución de cualquier método público, sin importar el tipo que retorne, que comience con hacer, y sin importar la cantidad y tipo de parámetros que requiera, hacer lo siguiente:". Eso significaría mas o menos. Ahora examinemos lo que significa cada parte:

  • after(): Esto indica que el cuerpo se ejecutará después de algo. Ahora veamos ese algo.
  • execution ( ): esto significa que se toma como referencia una ejecución de lo que sigue:
  • public * hacer*(..): public nos indica que se buscará un método público cualquiera. El asterisco que sigue, indica que ademas no importa el tipo que retorna el método. hacer* significa que el nombre del método debe comenzar con la palabra "hacer" y no importa cómo termine (para eso está el asterisco luego de "hacer"). Y finalmente, los dos puntos entre paréntesis significa que no importa ni el tipo ni la cantidad de parámetros del método.

Entonces, revisemos la descripción informal del método: "Después dela ejecución de cualquier método que sea público, que retorne cualquier tipo de dato, que comience con "hacer" y sin importar el tipo y cantidad de parámetros", se debe ejecutar lo que se indica en el cuerpo. El cuerpo es muy simple: no es mas que aquello que hacía el método RegistrarMovimiento() que hicimos antes. Esto es un aspecto. Simple, ¿no? El aspecto, se encargará de ejecutar ese cuerpo de código cada vez que ocurra esa descripción informal.

Con esto, hemos solucionado el problema del apartado anterior. ¿Por qué? Porque hemos logrado aislar el comportamiento de registrar un movimiento, de forma tal que la clase Cuenta no conoce de su existencia. Por lo tanto, no hemos tenido que repetir ningún código dentro de la clase, y además, al aislar ese comportamiento en un sólo aspecto, este se hace más fácilmente mantenible, ya que si queremos modificar la forma en que se registran los movimientos sólo debemos modificar el cuerpo de ejecución del aspecto, y no preocuparnos por las clases del negocio.

Por supuesto, para compilar aspectos, no podemos usar el compilador de java, para eso usamos el compilador AspectJ que lo que hace es armar un código complementando el código base con el código de aspectos. Una vez que esta herramienta genera el código final, ahí si se puede correr sobre la máquina virtual de java.

16 comentarios:

  1. Siempre es bueno estar informado, este artículo es muy interesante.

    ResponderEliminar
  2. Debe ser la primera vez que comento un blog en mi vida.Despue de Leer este articulo me dio ganas Muy bueno , sin vueltas y desmitificando este tema. Aplausos

    ResponderEliminar
  3. Llevaba tiempo buscando un tutorial sobre POA ya que nunca había llegado a entender lo que era claramente.

    Muchas gracias. Un 10!!

    ResponderEliminar
  4. Muy buenas la explicación, muchas gracias

    ResponderEliminar
  5. Muchas gracias por la sencillez con la que lo explicas, si bien no utilizo java ya entiendo de que va la cosa... Por ejemplo en python existen los decoradores que realizan la misma tarea, me lo dejaste bien clarito, muchas gracias! :)

    ResponderEliminar
  6. La verdad te agradezco muchisimo por estas 3 entradas de POA. Hace bastante que vengo escuchando de este "paradigma" y no lograba terminar de entender que era, para que servia. Pero eso es cuestion del pasado, ahora que entiendo que es, voy a poder seguir aprendiendo a como usarlo. Realmente Muchas Gracias por tu aporte!

    ResponderEliminar
  7. Excelente explicación.. Gracias!

    ResponderEliminar
  8. Muchas gracias Ignacio. Gracias a ti ahora entiendo la POA.

    ResponderEliminar
  9. te puedo conocer alguna vez? y que me cuentes mas sobre todo esto que parece muy interesante, estoy por entrar a ing en informática

    ResponderEliminar
  10. Excelente!!!! Muy claro y entendible, muchas gracias por compartir

    ResponderEliminar
  11. Al igual que otro lector, no suelo comentar los artículos, pero si alguien se ha tomado el tiempo de explicar y redactar 3 artículos tan claramente entendible es lo menos que puedo hacer; luego de más o menos 4 años después de haber sido escrito sigue siendo útil :D
    Simplemente muchas gracias!!!.

    ResponderEliminar
  12. Estoy haciendo mi tesis sobre aspectos, y gracias a tu artículo he entendido muchas cosas. Felicitaciones tu explicación fue muy clara y simple.

    ResponderEliminar
  13. Sencillamente Genial, No conocia esto y lo veo muy Util

    ResponderEliminar

Comments are subject to moderation, only in order to avoid insults and disguising things.

Los comentarios están sujetos a moderación, solo con el fin de evitar insultos y cosas por el estilo.