Aspectos? No entendía para que sirven

Tema: Explicación de la Programación Orientada a Aspectos
Categoria: Explicación concreta / Conceptos de programación
Tecnologías / Componentes: AOP, Spring

Contenidos

1 Introducción

1.1 Pongamos un ejemplo:

2 Patrón de responsabilidad simple
2.1 Código repetido, esparcido y otros costos
3 Aspectos extiende a Objetos
3.1 Solución
4 Características de AOP
5 Tipo de aspectos
5.1 Con gran poder viene gran responsabilidad
6 Consideraciones
7 Patrón Proxy
8 Como se hace AOP en Spring
9 Usos comunes
10 Resumen

Una de mis dudas de hace mucho tiempo y que por más que me explicaban, no entendía para qué y dónde se puede aplicar la programación orientada a aspectos (AOP). Y fué hasta que Mario Arias (@dh44t) me iluminó.

Asi que a continuacion trataré de explicarlo y ojala aquellos que tengan mi mismo problema puedan superarlo también.

Introducción

Para empezar la orientación a aspectos no sustituye (de cierta manera) a la orientada a objetos (OOP); pero tampoco podría nada que ver con ella, por lo que no tienen dependencia. La AOP es una manera que va encima y podría extender a OOP.
Para ser más claros AOP sirve para intercomunicar, convivir y administrar eventos que suceden entre las diferentes hileras (tiers), o como malamente se conocen como "capas" 

para saber mas y el porque de hileras y no capas ver mi post "Web Tiers: Explicación"

Pongamos un ejemplo:

Supongamos que al finalizar un desarrollo nos piden que todos los métodos validen si el usuario tiene roles de privilegios para ejecutar dicho método o que al iniciar y antes de salir de cada método registremos un log.
De ahi comienza a surgir la duda: ¿dónde codificamos esto? ¿Dentro de cada método? Y si es dentro de cada método, ¿tengo que repetir el mismo código en cada uno?
Así que de entrada algo no está bien y seguro implica que estamos violando algún patrón de diseño.

Patrón de responsabilidad simple

Una de las premicias de la programación orientada a objetos dicta que cada objeto y cada método, en particular, deben ejecutar únicamente su tarea principal.
Entonces, ¿por qué debo meter código de seguridad o de loggeo a un método que es específico en ejecutar una cierta actividad? ¿Debo violar esta buen práctica sólo por requerimientos?

Código repetido, esparcido y otros costos

¿Debemos pagar el precio de tener código repetido y esparcido en todas nuestras clases? Esto conllevaría a que estamos obligados a duplicar el código en cada método nuevo que codifiquemos. Lo que a su vez provocaría un hoyo de seguridad o de falta de loggeo en caso que se nos olvide; y si en algún momento cambian los requerimientos tendremos que cambiarlo en toda la aplicación.

Aspectos extiende a Objetos

Estas desventajas, entre muchas otras más, surgen en requerimientos que implican intrusión en la responsabilidad de los métodos; y es para estos casos que AOP ayuda a solventar está problemática: pero con objetos.

Solución

Podemos crear una clase asignada para Aspectos, que cada método es el código que debemos ejecutar para la seguridad o el loggeo.

Luego tenemos que usar un contexto de aplicación donde le indicamos que aplique dicho código antes o después de ejecutar ciertos métodos (asignamos filtros).
De esta manera el contexto se encargará de estar pendiente de la ejecución de los métodos que cumplen nuestro filtro y ejecutará en el momento indicado el código que tenemos bien definido en nuestra clase de Aspectos.

¡Esto es programación orientada a aspectos!.

De esta manera no violamos la premicia de responsabilidad simple de cada método, tenemos nuestro codigo de seguridad y loggeo dentro de clases y métodos y tampoco cargamos con los costos antes mencionados: si cambian los requerimientos modificamos los metodos de la clase Aspectos. Si eliminan el requerimiento o lo limitan a ciertos métodos únicamente, modificamos el filtro que le dimos al contexto.

Características de AOP

Así como la OOP tiene sus 3 características que nos enseñan desde la escuela:

  • Herencia,
  • Encapsulamiento
  • y polimorfismo.

La Aop tiene las siguientes:

  • Punto de unión (join point): Es el punto definido en el código donde entrará el aspecto.
  • Punto de corte (point cut): Es la expresión que describe uno o varios puntos de uniones (los filtros)
  • Consejo (advice): Es el código que va a ser ejecutado en un cierto punto de corte
  • Aspecto (aspect): Es el encapsulamenteo de un PointCut y un Advice.

Tipo de aspectos

Ya entendiendo los aspectos tenemos que saber qué tipos de aspectos hay :

  • Antes (@Before). Estas definiciones se ejecutan antes de iniciar el método
  • Después (@After). Estos se ejecutan después de haber sido invocado el método pero antes de regresar su valor. Por lo que en esta definición podemos alterar y manipular el valor retornado. En Spring existen dos variaciones
    • @AfterReturning
    • @AfterThrowing
  • Alrededor (@Around). Este es el más completo y poderoso ya que se ejecuta antes de ser invocado el método y nosotros tenemos que invocarlo explícitamente; por lo que, tambien podemos obtener y manipular el valor de regreso o ejecutar o no el método.
Asi que dependiendo de nuestro requerimiento podemos utilizar cualquiera de estos tres.

Con gran poder viene gran responsabilidad

Hemos visto el alcance que la AOP  tiene y el poder de manipular los datos de entrada y de salida de los métodos y hasta podemos permitir o no la ejecución del método; o cosas mas extrañas como evitar que el método se ejecute y en su lugar invocar código nuestro y para el usuario del método será totalmente transparente.
En general podemos alterar el comportamiento de la aplicación.

Esto es excelente si tenemos código legado sin los fuentes para modificar, sin embargo también puede llevar a hoyos de seguridad o mal intencionados.

Así que úselo con precaucion y ética

Consideraciones

Obviamente no podemos manipular código que no esté siendo controlado por el contexto. Lo que significa que en el caso de Spring, los objetos deben ser tratados como beans. Es por eso que no podemos alterar tipos como String o de otras aplicaciones a menos que los definamos dentro del contesto de Spring.

Patrón Proxy

Quiero hacer un paréntesis para hacer una introducción al patron proxy (para más información ver wikipedia o el siguiente blog de patronesDeDiseño.)

A grandes rasgos este patrón soluciona el problema de controlar la invocación o acceso a un objeto y sus métodos.
Proxy en español significa "representante" por lo que un usuario de una clase hace peticiones a su representante y no al objeto específico. Por lo que el proxy puede hacer cierta lógica antes o después de llamar al método respectivo.
En UML se ve de la siguiente manera:

Para empezar debemos tener:

  • una interfaz. 
  • Después creamos la clase normal implementando a dicha interfaz.
  • Por otro lado, creamos otra clase proxy que implementa la misma interfaz y además tiene un atributo privado del tipo de la interfaz.

Por lo tanto el objeto proxy es (IS-A) y tiene (HAS-A) un tipo de esa interfaz.

Como se hace AOP en Spring

En el caso de Spring se hace mediante el patrón Proxy. Asi que en el momento de crear los objetos beans y hacer la inyección de dependencias, en lugar de insertar el objeto como referencia en otros beans realmente está insertando la referencia al proxy y a éste le inserta el objeto target (el objeto de nuestra implementación).
De esta manera, los aspectos que programamos serán la logica que se encuentra en el método Avanzar del Proxy y que ejecutará  antes o después de ejecutará  el método del objeto target que tiene en su atributo privado.

Usos comunes

Los usos comunes para utilizar aspectos son:

  • Seguridad. Validar algo antes de ejecutar un método.
  • Logs. Mostrar logs o auditoría
  • Popular repositorios. Al iniciar una aplicación ejecutar algo, por ejemplo popular una base de datos o auto instalarse y configurarse.

Resumen

Como hemos visto la programación orientada a aspectos complementa a la orientada a objetos pudiendo incrementar lógica a eventos o situaciones que pasan a lo largo de las hileras y que trasciende a la responsabilidad especifica de las clases.
Podemos diseñar aplicaciones totalmente basadas en AOP pero tenemos que tener cuidado en no alterar el comportamiento o los objetos. Para esto es recomendable tener pruebas de aceptación automatizadas.
Pero en general es un paradigma altamente útil que ya podemos utilizar en nuestros proyectos ya sea completa o parcialmente.

Post original del autor en: "java Arch Blog"

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de paranoid_android

¿El log con AOP?

Hola. En el caso de Log con programación orientada a aspectos ¿Has encontrado código? Saludos.

Imagen de neko069

Ejemplos de aspectos

Dejaré ésto por acá.
Ejemplo 1.
Ejemplo 2.
Ejemplo 3.
Ejemplo 4.
Ejemplo 5.

Imagen de paranoid_android

Muchas gracias

Muchas gracias Neko, probaremos los ejemplos. Saludos

wow

Muy buena explicación,, gracias

Imagen de bferro

hileras?

El término que uso para referirme al término en ingles "tier" es grada. No había oído el término hilera, pero viene bien.
Distinguir entre capa y grada (o hilera) no es trivial y por esa razón es que encuentras el uso de ambos.
La diferencia fundamental no está en la forma (sea ésta una cebolla o las gradas de un stadium). Los que gustamos de usar los dos términos, usamos el término capa en el estricto sentido del estilo arquitectónico basado en capas que trata de resolver una funcionalidad particular mediante capas de software que brindan sus servicios de"abajo hacia arriba". El ejemplo clásico es el stack de TCP/IP o el susodicho modelo OSI de 7 capas.
En ambos casos se requiere resolver una única funcionalidad que es la que dos máquinas puedan comunicarse entre sí.
Cuando se habla de la arquitectura de aplicaciones basadas en varias gradas, la situación es diferente. Cada grada se ocupa de un concern primario de la aplicación, por lo que las gradas o hileras resuelven diferentes funcionalidades de alto nivel.
Si la distinción se entiende entonces da lo mismo usar capa que grada o hilera.
En computación muchos términos están sobrecargados. Decimos: "ejecuta este programa", cuando en realidad los programas no se ejecutan, lo que se ejecuta es el proceso instancia de ese programa. Y así con muchas cosas.