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



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" 

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.

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.

Tipos

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.

Responsabilidad

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 Similares

TituloDescripciónCategoriaTecnologíasTipoFecha de publicación
Subversión y Jenkins: cómo comunicarse entre ellos Como poder indicarle a Jenkins iniciar una actividad cuando Subversion ha sido actualizado Integración continua Subversion, Jenkins Tip 17 de septiembre de 2012 
Jenkins & Sonar: Status en jenkins refleje alertas de sonar Cómo poder mostrar en Jenkins el status real dependiendo de las alertas de Sonar Integración continua Subversion, Jenkins Tip 29 de agosto de 2012 
Web Tiers: Explicación Explicación sobre el concepto "tiers" en proyectos web. Diseño Servlets Explicación 1 de septiembre de 2009 
Tipo de Pruebas para Desarrollo de Software Explicación sobre los diferentes tipos de pruebas que se pueden hacer en el desarrollo de software Calidad XUnit, Sonar, PMD, Findbugs, Thucydides, Checkstyle, Cobertura Explicación 11 de septiembre de 2012 
Integración Continua: Promociones y Líneas de Producción  Explicación del concepto de promociones y pipelines en Integración Continua Integración continua Jenkins y plugins Explicación 27 de septiembre de 2012 
Mostrando 5 elementos de la página Indice de posts ordenados por hora de edición. Ver más »

Comments