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.
Siempre es bueno estar informado, este artículo es muy interesante.
ResponderEliminarDebe 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
ResponderEliminarLlevaba tiempo buscando un tutorial sobre POA ya que nunca había llegado a entender lo que era claramente.
ResponderEliminarMuchas gracias. Un 10!!
Genial Ignacio! gracias!!
ResponderEliminarMuy buenas la explicación, muchas gracias
ResponderEliminarMuchas 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! :)
ResponderEliminarLa 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!
ResponderEliminarExcelente explicación.. Gracias!
ResponderEliminarMuchas gracias Ignacio. Gracias a ti ahora entiendo la POA.
ResponderEliminarte puedo conocer alguna vez? y que me cuentes mas sobre todo esto que parece muy interesante, estoy por entrar a ing en informática
ResponderEliminarExcelente!!!! Muy claro y entendible, muchas gracias por compartir
ResponderEliminarAl 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
ResponderEliminarSimplemente muchas gracias!!!.
Entendido todo !
ResponderEliminargracias
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.
ResponderEliminarMuy Buena explicación.
ResponderEliminarGracias
Sencillamente Genial, No conocia esto y lo veo muy Util
ResponderEliminar