Sunday, April 24, 2005

Introduction to Aspect Oriented Programming

Para resolver los problemas vistos en: What's AOP? se desarrollaron conceptos y tecnologías bajo el nombre de Aspect Oriented Programming. Para poder entender los conceptos que se manejan en AOP enumeraré las terminologías mas utilizadas:

  • Point-cut: Un pointcut describe un punto de ejecución del sistema. Puede estar compuesto por otros pointcuts. Los pointcuts pueden indicar una llamada a un método, la creación de un objeto, la escritura o lecturas de variables, el flujo en estructuras de control (if, while, for, etc), excepciones, el uso de una clase en particular entre otras cosas.
  • Advice: Comprende el código que se ejecuta cuando se alcanza el punto de ejecución (join-point). Una analogía posible, para el mejor entendimiento de este concepto, se da con el paradigma de Objetos donde se distinguen los menajes y los métodos, entonces en AOP el Advice es análogo al método y el pointcut es análogo al mensaje.
  • Join-point: Es el punto de ejecución que esta definido en el pointcut. Es el instante de ejecución por donde esta pasando el sistema. Es el lugar donde el Aspecto (Aspect) provee su servicio.
  • Aspect: Es el conjunto dado por el Poincut y el Advice. Es la definición del servicio o tarea que se debe ejecutar.
  • Introduction or mixin: Es la capacidad de hacer que una clase existente extienda de otra clase independiente de su árbol de jerarquía. O sea, se modifica una clase para que tenga método, interfaces, variables de otra clase. Esta característica es muy poderosa y permite, básicamente, crear múltiple herencia.
  • Cross-cutting-concerns: Cada parte de un sistema tiene un objetivo principal, pero para conseguir su objetivo necesita de tareas secundarias que son comunes a todo el sistema. Por ejemplo, que los objetos sean transaccionales es una característica transversal a la misión de cada objeto, pero es necesaria para el cumplimiento de sus objetivos.

Para concluir con esta breve introducción analicemos el caso del Productor-Cosumidor, donde se accede a un buffer, pero este acceso debe ser sincronizado. La misión principal del Productor es llenar el buffer y la del Cosumidor es vaciarlo. Pero si ambos no están sincronizados no podrán concluir con éxito su objetivo. A nivel código tendremos que lidiar con lo específico de la sincronización mezclado con el código de la misión principal. En este punto es donde se dislumbra que la sincronización es un aspecto del problema del Productor-Consumidor y ponemos el código de sincronización como Advise. Entonces tendremos separadas las tareas necesarias para ejecutar la tarea principal; hemos separado las incumbencias. Como consecuencia nos quedará un código más claro, o sea, mejoramos la calidad del código.