Está en la página 1de 123

www.programemos.

com

Programemos en AspectJ

Mariano Lorente Lpez Fernando Asteasuain Bernardo Ezequiel Contreras


Versin 1.1 12 Septiembre de 2005

www.programemos.com Pgina 1/123

www.programemos.com

NDICE 1. INTRODUCCIN....................................................................................................... 5 1.1 RESEA HISTRICA....................................................................................................... 7 2. POA: CONSIDERACIONES GENERALES......................................................... 10 2.1 QU ES UN ASPECTO?...............................................................................................10 2.2 COMPARACIN GRFICA.............................................................................................. 11 2.3 FUNDAMENTOS DE LA POA.........................................................................................13 2.3.1 Estructura general..........................................................................................14 PROGRAMA...............................................................................................................14 LENGUAJE................................................................................................................... 14 2.3.2 Desarrollo orientado a aspectos.................................................................... 15 2.4 TEJIDO ESTTICO VERSUS DINMICO.............................................................................. 18 2.4.1 Guas de diseo.............................................................................................. 19 2.5 LENGUAJES DE ASPECTOS ESPECFICOS VERSUS DE PROPSITO GENERAL............................... 19 2.6 EL ROL DEL LENGUAJE BASE......................................................................................... 21 2.7 ASPECTOS EN LENGUAJES PROCEDURALES....................................................................... 22 2.8 APROXIMACIONES ALTERNATIVAS DE ASPECTOS.............................................................. 26 2.8.1 Meta-programacin lgica de aspectos......................................................... 26 2.8.2 Meta-programacin funcional de aspectos....................................................29 3. LENGUAJES ORIENTADOS A ASPECTOS ...................................................... 31 3.1 JPAL...................................................................................................................... 31 3.2 D............................................................................................................................ 32 3.2.1 COOL............................................................................................................. 33 3.2.2 RIDL............................................................................................................... 34 3.3 ASPECTC..............................................................................................................36 3.4 ASPECTS ............................................................................................................. 36 3.5 ASPECTC++......................................................................................................... 38 3.6 MALAJ.................................................................................................................. 39 3.7 HYPERJ.................................................................................................................40 3.8 TABLA COMPARATIVA DE LAS HERRAMIENTAS..................................................................42 3.9 ASPECTJ..................................................................................................................44 4. REFERENCIA ASPECTJ........................................................................................ 46 4.1 ASPECTS................................................................................................................... 46 4.1.1 Aspect............................................................................................................. 47 4.1.2 extends, implements........................................................................................48 4.1.3 pertarget, perthis............................................................................................50 4.1.4 percflow, percflowbelow................................................................................ 53 4.1.5 issingleton...................................................................................................... 55 4.2 POINTCUT DEFINITIONS................................................................................................ 56 4.2.1 private pointcut Id() : call([ModifiersPat] ................................................... 56 TypePat [TypePat.].IdPat(TypePat | .., ...));.......................................................... 56 4.2.2 pointcut Id(Type param) : set([ModifiersPat] [TypePat.] new (TypePat | .., ...)) [throws ThrowsPat];.................................................................................. 56
www.programemos.com Pgina 2/123

www.programemos.com

4.2.3 public abstract pointcut Id();......................................................................... 56 4.2.4 abstract pointcut Id(Object o);.......................................................................56 4.3 COMODINES Y OPERADORES DEL POINTCUT..................................................................... 64 4.4 PRIMITIVE POINTCUTS................................................................................................. 65 4.4.1 call(MethodPat), call(ConstructorPat).......................................................... 66 4.4.2 execution(MethodPat), execution(ConstructorPat)....................................... 66 4.4.3 This(TypePat)................................................................................................. 74 4.4.4 Target(TypePat)............................................................................................. 74 4.4.5 Args(TypePat)................................................................................................ 74 4.4.6 initialization(ConstructorPat)........................................................................74 4.4.7 preinitialization(ConstructorPat)...................................................................74 4.4.8 staticinitialization(TypePat)...........................................................................74 4.4.9 get(FieldPat).................................................................................................. 76 4.4.10 set(FieldPat).................................................................................................77 4.4.11 handler(TypePat)..........................................................................................79 4.4.12 adviceexecution()..........................................................................................80 4.4.13 withincode(ConstructorPat).........................................................................81 4.4.14 within(TypePat)............................................................................................ 82 4.4.15 Cflow(Pointcut) ........................................................................................... 82 4.4.16 Cflowbelow(Pointcut)...................................................................................82 4.4.17 If().................................................................................................................82 4.5. JOIN POINT ..............................................................................................................83 4.6. ADVICE DECLARATIONS............................................................................................. 84 4.6.1 Before(Formals):............................................................................................84 4.6.2 after (Formals)............................................................................................... 86 4.6.3 after (Formals) returning [ (Formal) ].......................................................... 87 4.6.4 after (Formals) throwing [ (Formal) ]...........................................................87 4.6.5 Type around (Formals).................................................................................. 88 5. CONCLUSIONES FINALES...................................................................................90 5.1 BREVE COMPARACIN ENTRE POA Y POO................................................................... 90 5.2 TRABAJOS RELACIONADOS............................................................................................91 5.3 POA: VENTAJAS Y DESVENTAJAS.................................................................................92 5.3.1 Ventajas .........................................................................................................92 5.3.2 Desventajas.................................................................................................... 93 REFERENCIAS.............................................................................................................94 3.9.1 Puntos de enlace.............................................................................................98 3.9.2 Cortes........................................................................................................... 102 3.9.3 Avisos........................................................................................................... 112 3.9.4 Introducciones y declaraciones....................................................................116 3.9.5 Aspectos........................................................................................................118 3.9.6 Evaluacin....................................................................................................123

www.programemos.com Pgina 3/123

www.programemos.com

1. Introduccin
La ingeniera del software ciertamente ha evolucionado desde sus comienzos. Al principio, se tena un cdigo en el que no exista la separacin de conceptos; datos y funcionalidad se mezclaban sin una lnea que los dividiera claramente. A esta etapa se la conoce como cdigo spaghetti, debido a que se tena una maraa entre datos y funcionalidad similar a la que se forma al comer un plato de esta comida italiana. A medida que la ingeniera de software fue creciendo, se fueron introduciendo conceptos que llevaron a una programacin de ms alto nivel: la nocin de tipos, bloques estructurados, agrupamientos de instrucciones a travs de procedimientos y funciones como una forma primitiva de abstraccin, unidades, mdulos, tipos de datos abstractos, genericidad, herencia. Como vemos, los progresos ms importantes se han obtenido aplicando tres principios, los cuales estn estrechamente relacionados entre s: abstraccin, encapsulamiento, y modularidad. Esto ltimo consiste en la nocin de descomponer un sistema complejo en subsistemas ms fciles de manejar, siguiendo la antigua tcnica de dividir y conquistar. Un avance importante lo introdujo la Programacin Orientada a Objetos (POO), donde se fuerza el encapsulamiento y la abstraccin, a travs de una unidad que captura tanto funcionalidad como comportamiento y estructura interna. A esta entidad se la conoce como clase. La clase hace nfasis tanto en los algoritmos como en los datos. La POO est basada en cuatro conceptos [17]: Definicin de tipos de datos abstractos. Herencia Encapsulamiento. Polimorfismo por inclusin. La herencia es un mecanismo lingstico que permite definir un tipo de dato abstracto derivndolo de un tipo de dato abstracto existente. El nuevo tipo definido hereda las propiedades del tipo padre [17]. Ya sea a travs de la POO o con otras tcnicas de abstraccin de alto nivel, se logra un diseo y una implementacin que satisface la funcionalidad bsica, y con una calidad aceptable. Sin embargo, existen conceptos que no pueden encapsularse dentro de una unidad funcional, debido a que atraviesan todo el sistema, o varias parte de l (crosscutting concerns). Algunos de estos conceptos son: sincronizacin, manejo de memoria, distribucin, chequeo de errores, profiling, seguridad o redes, entre otros. As lo muestran los siguientes ejemplos: 1) Consideremos una aplicacin que incluya conceptos de seguridad y sincronizacin, como por ejemplo, asegurarnos que dos usuarios no intenten acceder al mismo dato al mismo tiempo. Ambos conceptos requieren que los programadores escriban la misma funcionalidad en varias partes de la aplicacin. Los programadores se vern forzados a recordar todas estas partes, para que a la hora de efectuar un cambio y / o una actualizacin puedan hacerlo de manera uniforme a travs de
www.programemos.com Pgina 4/123

www.programemos.com

todo el sistema. Tan solo olvidarse de actualizar algunas de estas repeticiones lleva al cdigo a acumular errores [4]. 2) Manejo de errores y de fallas: agregar a un sistema simple un buen manejo de errores y de fallas requiere muchos y pequeos cambios y adiciones por todo el sistema debido a los diferentes contextos dinmicos que pueden llevar a una falla, y las diferentes polticas relacionadas con el manejo de una falla [8]. En general, los aspectos en un sistema que tengan que ver con el atributo performance, resultan diseminados por todo el sistema [8].

3)

Las tcnicas de implementacin actuales tienden a implementar los requerimientos usando metodologas de una sola dimensin, forzando los requerimientos a ser expresados en esa nica dimensin. Esta dimensin resulta adecuada para la funcionalidad bsica y no para los requerimientos restantes, los cuales quedan diseminados a lo largo de la dimensin dominante. Es decir, que mientras el espacio de requerimientos es de n-dimensiones, el espacio de la implementacin es de una sola dimensin. Dicha diferencia resulta en un mapeo deficiente de los requerimientos a sus respectivas implementaciones. Algunos sntomas de este problema pueden ser categorizados de la siguiente manera [18]: 1. Cdigo Mezclado (Code Tangling): En un mismo mdulo de un sistema de software pueden simultneamente convivir ms de un requerimiento. Esta mltiple existencia de requerimientos lleva a la presencia conjunta de elementos de implementacin de ms de un requerimiento, resultando en un Cdigo Mezclado. 2. Cdigo Diseminado (Code Scattering): Como los requerimientos estn esparcidos sobre varios mdulos, la implementacin resultante tambin queda diseminada sobre esos mdulos. Estos sntomas combinados afectan tanto el diseo como el desarrollo de software, de diversas maneras [18]: Baja correspondencia: La implementacin simultnea de varios conceptos oscurece la correspondencia entre un concepto y su implementacin, resultando en un pobre mapeo. Menor productividad: La implementacin simultnea de mltiples conceptos distrae al desarrollador del concepto principal, por concentrarse tambin en los conceptos perifricos, disminuyendo la productividad. Menor reuso: Al tener en un mismo mdulo implementados varios conceptos, resulta en un cdigo poco reusable. Baja calidad de cdigo: El Cdigo Mezclado produce un cdigo propenso a errores. Adems, al tener como objetivo demasiados conceptos al mismo tiempo se corre el riesgo de que algunos de ellos sean subestimados.

www.programemos.com Pgina 5/123

www.programemos.com

Evolucin ms dificultosa: Como la implementacin no est completamente modularizada los futuros cambios en un requerimiento implican revisar y modificar cada uno de los mdulos donde est presente ese requerimiento. Esta tarea se vuelve compleja debido a la insuficiente modularizacin.

Tenemos entonces que las descomposiciones actuales no soportan una completa separacin de conceptos, la cual es clave para manejar un software entendible y evolucionable. Podemos afirmar entonces que las tcnicas tradicionales no soportan de una manera adecuada la separacin de las propiedades de aspectos distintos a la funcionalidad bsica, y que esta situacin tiene un impacto negativo en la calidad del software. Como respuesta a este problema nace la Programacin Orientada a Aspectos (POA). La POA permite a los programadores escribir, ver y editar un aspecto diseminado por todo el sistema como una entidad por separado, de una manera inteligente, eficiente e intuitiva. La POA es una nueva metodologa de programacin que aspira a soportar la separacin de las propiedades para los aspectos antes mencionados. Esto implica separar la funcionalidad bsica y los aspectos, y los aspectos entre s, a travs de mecanismos que permitan abstraerlos y componerlos para formar todo el sistema. La POA es un desarrollo que sigue a la POO, y como tal, soporta la descomposicin orientada a objetos, adems de la procedimental y la funcional. Sin embargo, la programacin orientada a aspectos no es una extensin de la POO, ya que puede utilizarse con los diferentes estilos de programacin mencionados anteriormente. Teniendo en cuenta nuevamente la forma en que la ingeniera de software ha crecido, siempre de la mano de nuevas formas de descomposicin que implicaron luego nuevas generaciones de sistemas, es vlido preguntarnos si tambin de la mano de la POA nacer una nueva generacin de sistemas de software. 1.1 Resea histrica1 An antes de que surgiera el concepto de programacin orientada a aspectos, el grupo Demeter[13] haba considerado y aplicado ideas similares. El concepto principal detrs del trabajo del grupo Demeter es la programacin adaptativa (PA), la cual puede verse como una instancia temprana de la POA. El trmino programacin adaptativa se introdujo recin en 1991. La programacin adaptativa constituye un gran avance dentro de la tecnologa de software, basada en el uso de autmatas finitos y una teora formal de lenguaje para expresar concisamente y procesar eficientemente conjuntos de caminos en un grafo arquitectnico, como por ejemplo los diagramas de clase en UML.

El desarrollo histrico se obtuvo de la pgina del grupo de Demeter[13], para los interesados en profundizar en la historia.
www.programemos.com Pgina 6/123

www.programemos.com

La relacin entre la POA y la PA surge de la Ley de Demeter: Solo conversa con tus amigos inmediatos. Esta ley inventada en 1987 en la Northeastern University y popularizada en libros de Booch, Budd, Coleman, Larman, Page-Jones, Rumbaugh, entre otros, es una simple regla de estilo en el diseo de sistemas orientados a objetos. Para poder escribir cdigo respetando la Ley de Demeter observaron que los conceptos que se entrecruzan entre varias clases deberan y tendran que ser claramente encapsulados. Esto resultara en una clara separacin de los conceptos de comportamiento y de aquellos conceptos de la funcionalidad bsica. Por lo tanto la separacin completa de conceptos fue rea de inters de este grupo an antes de que la POA existiera como tal. En 1995 dos miembros de este grupo, Cristina Lopes, actualmente integrante del grupo Xerox PARC, y Walter Huersch, presentaron un reporte tcnico sobre separacin de conceptos[13] incluyendo varias tcnicas como filtros composicionales y PA para tratar con los conceptos que se entrecruzan. Este reporte identific el tema general de separacin de conceptos y su implementacin, y lo propuso como uno de los problemas a resolver ms importante en el diseo y desarrollo de software. La definicin formal de PA puede considerarse como una definicin inicial y general de la POA: en PA los programas se descomponen en varios bloques constructores de corte (crosscutting building blocks). Inicialmente separaron la representacin de los objetos como un bloque constructor por separado. Luego agregaron comportamiento de estructura (structure-shy behavior) y estructuras de clase como bloques constructores de corte. La primera definicin del concepto de aspecto fue publicada en 1995, tambin por el grupo Demeter, y se describa de la siguiente forma: Un aspecto es una unidad que se define en trminos de informacin parcial de otras unidades. La definicin de aspectos ha evolucionado desde entonces hasta llegar a la definicin actual, que ser citada ms adelante en este trabajo. Cristina Lopes y Karl Lieberherr empezaron a trabajar con Gregor Kickzales y su grupo. A Lopes y Kickzales no les gust el nombre Programacin Adaptativa e introdujeron un mejor trmino Programacin Orientada a Aspectos con su propia definicin y terminologa. En la literatura se lo considera a Gregor Kickzales como el creador de este nuevo paradigma. Al crecer la POA como paradigma fue posible definir la PA como un caso de especial de la POA[13], esto es, la PA es igual a la POA con grafos y estrategias transversales. Las estrategias transversales podran considerarse como expresiones regulares que especifican un recorrido en un grafo. La POA es un paradigma que recin est naciendo. Se estn realizando las primeras experiencias prcticas para mostrar su aplicabilidad, y obtener datos empricos que estimulen la investigacin en el tema. La POA est en su primera etapa, donde constantemente surgen nuevos problemas, nuevas herramientas, nuevos contextos en los cuales es posible aplicar aspectos. Este panorama hace pensar que la programacin

www.programemos.com Pgina 7/123

www.programemos.com

orientada a aspectos se encuentra en mismo lugar que se encontraba la POO hace veinte aos.

www.programemos.com Pgina 8/123

www.programemos.com

2. POA: Consideraciones generales


La idea central que persigue la POA es permitir que un programa sea construido describiendo cada concepto separadamente. El soporte para este nuevo paradigma se logra a travs de una clase especial de lenguajes, llamados lenguajes orientados a aspectos (LOA), los cuales brindan mecanismos y constructores para capturar aquellos elementos que se diseminan por todo el sistema. A estos elementos se les da el nombre de aspectos. Una definicin para tales lenguajes sera: Los LOA son aquellos lenguajes que permiten separar la definicin de la funcionalidad pura de la definicin de los diferentes aspectos. Los LOA deben satisfacer varias propiedades deseables [7], entre ellas: Cada aspecto debe ser claramente identificable. Cada aspecto debe auto-contenerse. Los aspectos deben ser fcilmente intercambiables. Los aspectos no deben interferir entre ellos. Los aspectos no deben interferir con los mecanismos usados para definir y evolucionar la funcionalidad, como la herencia. 2.1 Qu es un aspecto? Gregor Kickzales y su grupo, en [8], brinda un marco adecuado que facilita y clarifica la definicin de un aspecto. Lo que propone es agrupar los lenguajes orientados a objetos, los procedurales y funcionales como lenguajes de procedimiento generalizado (LPG), ya que sus mecanismos claves de abstraccin y composicin pueden verse como agrupados bajo una misma raz. Esa raz tendra la forma de un procedimiento generalizado. Los mtodos de diseo que han surgido para los LPG tienden a dividir el sistema en unidades de comportamiento o funciones. A este estilo se lo conoce como descomposicin funcional [11-12] (si bien la naturaleza exacta de la descomposicin funcional difiere entre los paradigmas, para los propsitos de este trabajo alcanza con agruparlos bajo LPG). En general, decimos que dos propiedades se entrecruzan si al implementarse deben componerse de manera diferente, y an deban ser coordinadas. Esto se debe a que tienen un comportamiento en comn. Al proveer los LPG solamente un nico medio de composicin, es el programador quien debe realizar la tarea extra de cocomponer manualmente las propiedades que se entrecruzan, lo cual lleva a un oscurecimiento y a un aumento de la complejidad del cdigo. Gracias a todo este marco, descripto en [8], podemos diferenciar los aspectos de los dems integrantes del sistema: al momento de implementar una propiedad, tenemos que la misma tomar una de las dos siguientes formas: Un componente: si puede encapsularse claramente dentro de un procedimiento generalizado. Un elemento es claramente encapsulado si est bien localizado, es fcilmente accesible y resulta sencillo componerlo.
www.programemos.com Pgina 9/123

www.programemos.com

Un aspecto: si no puede encapsularse claramente en un procedimiento generalizado. Los aspectos tienden a ser propiedades que afectan la performance o la semntica de los componentes en forma sistemtica (Ejemplo: sincronizacin, manejo de memoria, distribucin, etc.) A la luz de estos trminos, podemos enunciar la meta principal de la POA: brindar un contexto al programador que permita separar claramente componentes y aspectos, separando componentes entre s, aspectos entre s, y aspectos de componentes, a travs de mecanismos que hagan posible abstraerlos y componerlos para producir el sistema completo. Tenemos entonces una importante y clara diferencia respecto de los LPG, donde todos los esfuerzos se concentran nicamente en los componentes, dejando de lado los aspectos. Una vez diferenciados los aspectos de los componentes, estamos en condiciones de definir a un aspecto como un concepto que no es posible encapsularlo claramente, y que resulta diseminado por todo el cdigo. Los aspectos son la unidad bsica de la programacin orientada a aspectos. Una definicin ms formal, y con la que se trabaja actualmente es: Un aspecto es una unidad modular que se disemina por la estructura de otras unidades funcionales. Los aspectos existen tanto en la etapa de diseo como en la de implementacin. Un aspecto de diseo es una unidad modular del diseo que se entremezcla en la estructura de otras partes del diseo. Un aspecto de implementacin es una unidad modular del programa que aparece en otras unidades modulares del programa. Dicha definicin pertenece al creador de la POA, Gregor Kickzales. 2.2 Comparacin grfica Ahora que ya hemos introducido los principales rasgos de la POA, podemos comparar la forma de una implementacin basada en los LPG versus implementacin basada en POA.

Funciona lidad bsica Aspecto de distribuci Aspecto de sincroniz Implementacin LPG Figura 1: Implementacin POA versus LPG. Implementacin POA

En la implementacin sobre LPG, los aspectos se mezclan con la funcionalidad bsica, y entre ellos. En cambio, en la implementacin basada en el nuevo paradigma de la
www.programemos.com Pgina 10/123

www.programemos.com

POA, la separacin es completa, con una notable mejora en lo que respecta a la modularizacin. Tambin podemos comparar las diferentes tecnologas que han sido creadas hasta la actualidad, con el paradigma de aspectos, observando la evolucin que han tenido las tecnologas. Tecnologa Programacin estructurada Programacin modular Abstraccin de datos Programacin orientada a objetos Conceptos Claves Constructores de control explcitos Ocultamiento Informacin de Constructores Do, while, iteradores y otros

Mdulos con interfaces bien definidas Tipo de dato abstracto Clases, polimorfismo Aspectos objetos,

Ocultar la representacin del dato Objetos con clasificacin y especializacin

Programacin orientada a 6 C y 4 S aspectos. Tabla 1: Comparacin entre los paradigmas

Las 6 C , de Mehmet Aksit, hacen referencia a los seis aspectos cuyos nombres en ingls comienzan con la letra c y que son los siguientes: Entrecruzado (Crosscutting en ingls) : el concepto ya ha sido introducido previamente en este trabajo. Cannico : brindar una implementacin estable para los conceptos. Composicin: proveer factores de calidad, como adaptabilidad, reusabilidad y extensibilidad. Clausura: mantener los factores de calidad del diseo en la etapa de implementacin. Computabilidad: crear software ejecutable. Certificabilidad: evaluar y controlar la calidad de los modelos de diseo e implementacin. Las 4 S hacen referencia a conceptos sobre Separacin Exitosa, de Harold Ossher, y corresponden a: Simultneo: la coexistencia de diferentes composiciones son importantes. Auto-Contenido(Self-Contained): Cada mdulo debe declarar sus dependencias, para poderlo entenderlo individualmente. Simtrico: no debe haber distincin en la forma en que los diferentes mdulos encapsulan los conceptos, para obtener una mayor confiabilidad en la composicin.

www.programemos.com Pgina 11/123

www.programemos.com

Espontaneidad (Spontaneous): debe ser posible identificar y encapsular nuevos conceptos, y an nuevas formas de conceptos que se presenten durante el ciclo de vida del software. 2.3 Fundamentos de la POA Los tres principales requerimientos de la POA son: [19] Un lenguaje para definir la funcionalidad bsica, conocido como lenguaje base o componente. Podra ser un lenguaje imperativo, o un lenguaje no imperativo (C++, Java, Lisp, ML). Uno o varios lenguajes de aspectos, para especificar el comportamiento de los aspectos. (COOL, para sincronizacin, RIDL, para distribucin, AspectJ, de propsito general.) Un tejedor de aspectos(Weaver), que se encargar de combinar los lenguajes. Tal proceso se puede retrasar para hacerse en tiempo de ejecucin o en tiempo de compilacin. Los lenguajes orientados a aspectos definen una nueva unidad de programacin de software para encapsular aquellos conceptos que cruzan todo el cdigo. A la hora de tejer los componentes y los aspectos para formar el sistema final, es claro que se necesita una interaccin entre el cdigo de los componentes y el cdigo de los aspectos. Tambin es claro que esta interaccin no es la misma interaccin que ocurre entre los mdulos del lenguaje base, donde la comunicacin est basada en declaraciones de tipo y llamadas a procedimientos y funciones. La POA define entonces una nueva forma de interaccin, provista a travs de los puntos de enlace (join points). Los puntos de enlace brindan la interfaz entre aspectos y componentes; son lugares dentro del cdigo donde es posible agregar el comportamiento adicional que destaca a la POA. Dicho comportamiento adicional es especificado en los aspectos. An nos falta introducir el encargado principal en el proceso de la POA. Este encargado principal conocido como tejedor debe realizar la parte final y ms importante: tejer los diferentes mecanismos de abstraccin y composicin que aparecen tanto en los lenguajes de aspectos como en los lenguajes de componentes, guiado por los puntos de enlace.

www.programemos.com Pgina 12/123

www.programemos.com

2.3.1 Estructura general

La estructura de una implementacin basada en aspectos es anloga a la estructura de una implementacin basada en los LPG. Una implementacin basada en LPG consiste en: [8] Un lenguaje. Un compilador o intrprete para ese lenguaje. Un programa escrito en ese lenguaje que implemente la aplicacin. La figura 2 nos permite visualizar grficamente la estructura anterior. PROGRAMA

Lengua je COMPILADOR | INTRPRETE

EJECUTABL E Figura 2: Estructura LPG. Una implementacin basada en POA consiste en: [8] El lenguaje base o componente para programar la funcionalidad bsica. Uno o ms lenguajes de aspectos para especificar los aspectos. Un tejedor de aspectos para la combinacin de los lenguajes. El programa escrito en el lenguaje componente que implementa los componentes. Uno o ms programas de aspectos que implementan los aspectos. Grficamente, se tiene una estructura como la siguiente:

www.programemos.com Pgina 13/123

www.programemos.com

PROGRAM A DE COMPONE

PROGRAM A DE ASPECTOS

Len guaj e

Lenguaj e de aspecto

. .

PROGRAM A DE ASPECTOS

Lenguaj e de aspecto

TEJEDOR (WEAVER)

EJECUTA BLE Figura 3: Estructura POA Cabe notar que la funcin que realizaba el compilador se encuentra ahora incluida en las funciones del tejedor.
2.3.2 Desarrollo orientado a aspectos

Disear un sistema basado en aspectos requiere entender qu se debe incluir en el lenguaje base, qu se debe incluir dentro de los lenguajes de aspectos y qu debe compartirse entre ambos lenguajes. El lenguaje componente debe proveer la forma de implementar la funcionalidad bsica y asegurar que los programas escritos en ese lenguaje componente no interfieran con los aspectos. Los lenguajes de aspectos tienen que proveer los medios para implementar los aspectos deseados de una manera intuitiva, natural y concisa[8]. En general el desarrollo de una aplicacin basada en aspectos consiste de tres pasos [18]: Descomposicin de aspectos: es descomponer los requerimientos para distinguir aquellos que son componentes de los que son aspectos. Implementacin de requerimientos: implementar cada requerimiento por separado. Recomposicin: dar las reglas de recomposicin que permitan combinar el sistema completo. En [14], John Lamping propone una diferente visin del diseo. Asegura que la decisin sobre qu conceptos son base y cules deben ser manejados por aspectos es irrelevante, ya que no afectar demasiado a la estructura del programa, sino que la clave est en definir cules sern los tems de la funcionalidad bsica y cmo obtener
www.programemos.com Pgina 14/123

www.programemos.com

una clara separacin de responsabilidades entre los conceptos. La primera parte se hereda de la programacin no orientada a aspectos y tiene la misma importancia dentro de la POA ya que la misma mantiene la funcionalidad bsica. La segunda parte es inherente a la programacin orientada a aspectos. Esta parte es fundamental para una descomposicin de aspectos exitosa. Diferentes aspectos pueden contribuir a la implementacin de un mismo tem de la funcionalidad bsica y un slo aspecto puede contribuir a la implementacin de varios tems. Una buena separacin de responsabilidades entre los conceptos es lo que hace esto posible, porque el comportamiento introducido por los diferentes aspectos se enfoca en diferentes temas en cada caso, evitando gran parte de los conflictos. Lamping concluye que el trabajo del programador que utiliza POA es definir precisamente los tems de la funcionalidad bsica y obtener una buena separacin de responsabilidades entre los conceptos. Luego los aspectos le permitirn al programador separar los conceptos en el cdigo. Creemos que la propuesta de Lamping es solo una manera ms compleja de llegar a los tres pasos del desarrollo orientado a aspectos, enumerados al comienzo de esta seccin. Estos pasos nos proveen un camino ms natural y directo. Tenemos entonces dos formas de lograr el mismo resultado pero al seguir los tres pasos logramos el resultado de una manera ms apegada y coherente a la filosofa orientada a aspectos. En un reporte tcnico de la Universidad de Virginia [15], se establece que muchos de los principios centrales a la POO son ignorados dentro del diseo orientado a aspectos, como por ejemplo el ocultamiento de informacin, debido a que los aspectos tienen la habilidad de violar estos principios. Para esto se propone una filosofa de diseo orientada a aspectos que consiste de cuatro pasos: Un objeto es algo. Un aspecto no es algo. Es algo sobre algo. Los objetos no dependen de los aspectos. Los aspectos representan alguna caracterstica o propiedad de los objetos, pero no tienen control sobre los mismos. Un objeto es algo: un objeto existe por s mismo, es una entidad. Un aspecto no es algo. Es algo sobre algo: un aspecto se escribe para encapsular un concepto entrecruzado. Por definicin un aspecto entrecruza diferentes componentes, los cuales en la POO son llamados objetos. Si un aspecto no est asociado con ninguna clase, entonces entrecruza cero clases, y por lo tanto no tiene sentido en este contexto. Luego, para que un aspecto tenga sentido debe estar asociado a una o ms clases; no es una unidad funcional por s mismo. Los objetos no dependen de los aspectos: Un aspecto no debe cambiar las interfaces de la clases asociadas a l. Solo debe aumentar la implementacin de dichas interfaces. Al afectar solamente la implementacin de las clases y no sus interfaces, la encapsulacin no se rompe. Las clases mantienen su condicin original de cajas negras, an cuando puede modificarse el interior de las cajas.
www.programemos.com Pgina 15/123

www.programemos.com

Los aspectos no tienen control sobre los objetos: Esto significa que el ocultamiento de informacin puede ser violado en cierta forma por los aspectos porque stos conocen detalles de un objeto que estn ocultos al resto de los objetos. Sin embargo, no deben manipular la representacin interna del objeto ms all de lo que sean capaces de manipular el resto de los objetos. A los aspectos se les permite tener esta visin especial, pero debera limitarse a manipular objetos de la misma forma que los dems objetos lo hacen, a travs de la interface. Esta filosofa de diseo permite a los aspectos hacer su trabajo de automatizacin y abstraccin, respetando los principios de ocultamiento de informacin e interface manifiesta [16]. Creemos que sta filosofa es una poltica de diseo totalmente aceptable, y que se debe conocer y aplicar durante el desarrollo orientado a aspectos. Si bien es una excelente poltica de diseo, no deberamos quedarnos solamente en esto, sino que deberamos llevarla ms all, hacindola formar parte de las reglas del lenguaje orientado a aspectos. Esto es, que no sea una opcin, sino que sea forzada por el lenguaje. El mismo problema que antes exista entre las distintas componentes de un sistema, est presente ahora entre objetos y aspectos. Es decir, los aspectos no deben inmiscuirse en la representacin interna del objeto, por lo tanto se necesita una solucin similar: el lenguaje debera proveer una interface para que aspectos y objetos se comuniquen respetando esa restriccin. Esta es una de las desventajas de los lenguajes orientados a aspectos actuales. El desafo est en construir lenguajes orientados a aspectos capaces de brindar mecanismos lingsticos suficientemente poderosos para respetar por completo todos los principios de diseo.

www.programemos.com Pgina 16/123

www.programemos.com

2.4 Tejido esttico versus dinmico La primera decisin que hay que tomar al implementar un sistema orientado a aspectos es relativa a las dos formas de entrelazar el lenguaje componente con el lenguaje de aspectos. Dichas formas son el entrelazado o tejido esttico y el entrelazado o tejido dinmico. El entrelazado esttico implica modificar el cdigo fuente escrito en el lenguaje base, insertando sentencias en los puntos de enlace. Es decir, que el cdigo de aspectos se introduce en el cdigo fuente. Un ejemplo de este tipo de tejedor, es el tejedor de aspectos de AspectJ. El entrelazado dinmico requiere que los aspectos existan y estn presentes de forma explcita tanto en tiempo de compilacin como en tiempo de ejecucin. Para conseguir esto, tanto los aspectos como las estructuras entrelazadas se deben modelar como objetos y deben mantenerse en el ejecutable. Un tejedor dinmico ser capaz aadir, adaptar y remover aspectos de forma dinmica durante la ejecucin. Como ejemplo, el tejedor dinmico AOP/ST utiliza la herencia para aadir el cdigo especfico del aspecto a las clases, evitando modificar as el cdigo fuente de las clases al entrelazar los aspectos. Otro ejemplo ms completo sera el Junction Point Aspect Language (JPAL) [20], basado en los conceptos de protocolos de meta objetos (metaobject protocols MOP) y meta-programacin. En JPAL existe una entidad llamada Administrador de Programas de Aspectos el cual puede registrar un nuevo aspecto de una aplicacin y puede llamar a mtodos de aspectos registrados. Es implementado como una librera dinmica que almacena los aspectos y permite dinmicamente agregar, quitar o modificar aspectos, y mandar mensajes a dichos aspectos. El tejido esttico evita que el nivel de abstraccin introducido por la POA derive en un impacto negativo en la eficiencia de la aplicacin, ya que todo el trabajo se realiza en tiempo de compilacin, y no existe sobrecarga en ejecucin. Si bien esto es deseable el costo es una menor flexibilidad: los aspectos quedan fijos, no pueden ser modificados en tiempo de ejecucin, ni existe la posibilidad de agregar o remover nuevos aspectos. Otra ventaja que surge es la mayor seguridad que se obtiene efectuando controles en compilacin, evitando que surjan errores catastrficos o fatales en ejecucin. Podemos agregar tambin que los tejedores estticos resultan ms fciles de implementar y consumen menor cantidad de recursos. El tejido dinmico implica que el proceso de composicin se realiza en tiempo de ejecucin, decrementando la eficiencia de la aplicacin. El postergar la composicin brinda mayor flexibilidad y libertad al programador, ya que cuenta con la posibilidad de modificar un aspecto segn informacin generada en ejecucin, como tambin introducir o remover dinmicamente aspectos. La caracterstica dinmica de los aspectos pone en riesgo la seguridad de la aplicacin, ya que se puede dinmicamente remover comportamiento de un aspecto que quizs luego se requiera, o ms grave an, qu sucede si un aspecto en su totalidad es removido, y luego se hace mencin al
www.programemos.com Pgina 17/123

www.programemos.com

comportamiento de ese aspecto de otra manera. El tener que llevar mayor informacin en ejecucin, y tener que considerar ms detalles, hace que la implementacin de los tejedores dinmicos sea ms compleja. Es importante notar que la naturaleza dinmica hace referencia a caractersticas o propiedades de un aspecto, y no al aspecto en s mismo. Es decir, una vez que se identific un aspecto, el mismo se mantendr como concepto a lo largo de todo el ciclo de vida de la aplicacin. Lo que puede variar son las caractersticas o niveles de aplicacin de ese concepto. Por ejemplo, la comunicacin es esttica, en el sentido que el concepto de comunicacin est siempre presente, pero algunas caractersticas de la misma, como la velocidad o el costo, pueden cambiar por distintas razones en ejecucin. Es ms, quizs algunas propiedades de la comunicacin no se conozcan hasta ejecucin. Por lo tanto es necesario que el aspecto de comunicacin sea dinmico para adaptarse correctamente a los distintos casos de uso. Un ejemplo ms detallado de lo anterior se encuentra en [21], un estudio de aspectos dinmicos en la plataforma SMove.
2.4.1 Guas de diseo

Tomando como base la gua de diseo para la implementacin de sistemas abiertos, descripta en [22], podemos enunciar las siguientes pautas para aquellos tejedores que soporten tanto aspectos dinmicos como estticos: Los aspectos dinmicos deben separarse claramente de los aspectos estticos, como por ejemplo, a travs de un constructor o palabra reservada que indique la naturaleza del aspecto. En SMove[21], los aspectos estticos estn precedidos por la palabra reservada static, y los dinmicos por la palabra reservada dynamic. La especificacin de la naturaleza del aspecto debe ser opcional. El alcance de la influencia de dicha especificacin tiene que ser controlado de una forma natural y con suficiente granularidad. Esta pauta ayuda al programador a entender y razonar sobre su programa. El conocimiento que tiene el cliente sobre los detalles internos de implementacin debe ser minimal. Por ejemplo, el cliente podra elegir diferentes niveles de seguridad para el aspecto Seguridad-Edificio (alto, mediano o bajo) en ejecucin, sin conocer cmo est implementada cada alternativa. 2.5 Lenguajes de aspectos especficos versus de propsito general Existen dos enfoques principales en el diseo de los lenguajes de aspectos: los lenguajes de aspectos de dominio especfico y los lenguajes de aspectos de propsito general. Los lenguajes de aspectos de dominio especfico son capaces de manejar uno o ms aspectos, pero no pueden manejar otros aspectos ms all de los aspectos para los cuales fueron diseados. Tienen un mayor nivel de abstraccin que el lenguaje base, y expresan los conceptos de dominio especfico en un nivel de representacin ms alto. Para garantizar que los aspectos del dominio sean escritos en el lenguaje de aspectos, y evitar conflictos de control y dependencia entre el lenguaje base y el lenguaje de
www.programemos.com Pgina 18/123

www.programemos.com

aspectos, los lenguajes de dominio especficos imponen restricciones en la utilizacin del lenguaje base. Como ejemplo de este tipo de lenguaje de aspectos se puede nombrar a COOL (COOrdination Language), de Xerox [23], un lenguaje para sincronizacin de hilos concurrentes. En COOL, el lenguaje base es una restriccin de Java, ya que se han eliminado los mtodos wait, notify, y notifyAll, y la palabra reservada synchronized para evitar que el lenguaje base sea capaz de expresar sincronizacin. Se obtiene un mayor nivel de abstraccin que en Java al especificar la sincronizacin de hilos de manera declarativa. Un segundo ejemplo es RIDL(Remote Interaction and Data transfers Language), para el aspecto de distribucin: invocacin remota y transferencia de datos. Los lenguajes de aspectos de propsito general son diseados para describir cualquier clase de aspecto, no solo especficos, por lo que no pueden imponer restricciones al lenguaje base. El nivel de abstraccin del lenguaje base y del lenguaje de aspectos de propsito general es el mismo. Adems, tienen el mismo conjunto de instrucciones, ya que debe ser posible expresar cualquier cdigo al programar un aspecto. Un ejemplo es AspectJ, donde Java es el lenguaje base, y las instrucciones de los aspectos tambin se escriben en Java. La principal desventaja de los lenguajes de aspectos de propsito general es que no garantizan la separacin de conceptos, esto es, que la unidad de aspecto se utilice nicamente para programar el aspecto. Esto ltimo es uno de los objetivos principales de la POA. En comparacin, los lenguajes de aspectos de dominio especfico fuerzan la separacin de conceptos. Sin embargo, los de propsito general, proveen un ambiente ms adecuado para el desarrollo de aspectos. Es una nica herramienta capaz de describir todos los aspectos que se necesiten. Al pasar de una aplicacin a otra, por ejemplo al pasar de trabajar en un contexto de sincronizacin a uno de manejo de excepciones, se mantiene la misma herramienta para programar los aspectos. No se debe aprender para cada aplicacin todo de nuevo, que es costoso y hasta frustrante, sino que cada vez se obtiene una mayor experiencia, con lo cual programar nuevos aspectos es ms sencillo, y permite evolucionar los conceptos sobre el paradigma. Con los especficos, el pasar de una aplicacin a otra, significa comenzar de cero nuevamente, otros lenguajes, otras restricciones, que quizs sean similares, pero quizs sean completamente distintas. Si es el caso que se desee utilizar aspectos para una nica aplicacin, por una nica vez, entonces un lenguaje de aspectos de dominio especfico har un mejor papel, con una separacin de conceptos ms clara. Pero dada la gran variedad de aplicaciones en los cuales los aspectos pueden ser aplicados y observando las ventajas que trae un lenguaje de propsito general, es preferible esta ltima aproximacin siendo capaz de manejar varios ambientes de trabajo con el mismo lenguaje, reduciendo costos de aprendizaje y desarrollo.

www.programemos.com Pgina 19/123

www.programemos.com

2.6 El rol del lenguaje base Una de las decisiones relevantes a la hora de disear un lenguaje orientado a aspectos tiene que ver con el lenguaje base. Las distintas alternativas son: disear un nuevo lenguaje base o adoptar un lenguaje base existente. En el caso de adoptar un lenguaje base existente, es preferible que el mismo sea un lenguaje de propsito general, de manera de no restringir la aplicabilidad del lenguaje orientado a aspectos. Una ventaja obvia de esta opcin es el menor esfuerzo para disear e implementar lenguajes para ambientes orientados a aspectos, dado que nos ahorramos el trabajo que implica el diseo de un nuevo lenguaje base. Tambin, al trabajar con un lenguaje existente nos evitamos los problemas de trabajar con algo que todava no ha sido probado exhaustivamente. Una ltima ventaja radica en el hecho que el programador solo debe aprender el lenguaje de aspectos, y no tambin un nuevo lenguaje para la funcionalidad bsica, la cual sigue siendo, an en la POA, la parte ms grande del sistema. Si en cambio se elige disear un nuevo lenguaje base entonces se obtiene una mayor flexibilidad, una mayor libertad, y una manera ms natural de expresar aquellas abstracciones que forman parte de la funcionalidad bsica. Si bien estas ventajas son importantes, el costo de disear un nuevo lenguaje resulta demasiado alto. Sin embargo, existe otra, ms oculta, pero de mucha mayor trascendencia, dado que afecta directamente al corazn mismo de la POA, al surgir del enunciado de la meta principal que persigue este nuevo paradigma, la separacin completa de conceptos. Una gran parte de los investigadores que han trabajado con aspectos, establecen que no est claro si es posible lograr la separacin completa de conceptos utilizando un lenguaje base existente. Si esta posicin logra finalmente imponerse, entonces el futuro de la POA indica que el diseo de nuevos lenguajes base ser altamente necesario. En [2], K. Mehner y A. Wagner, de la Universidad de Paderborn, plantean una futura investigacin con respecto a este ltimo concepto. Estudiarn si en un domino de aplicacin ,como por ejemplo el dominio de sincronizacin de hilos concurrentes, la separacin de conceptos puede lograrse utilizando un lenguaje base existente. De no ser as investigarn si el problema ocurrir con cualquier lenguaje base de propsito general o si se debe construir un nuevo lenguaje base. Hasta ahora los lenguajes orientados a aspectos especficos y de propsito general han elegido utilizar un lenguaje base existente. Aparte de las ventajas de esta eleccin esto trae consigo una serie de problemas. En el caso de los lenguajes de dominio especfico uno no es completamente libre para disear los puntos de enlace sino que se restringe a aquellos que pueden ser identificados en el lenguaje base. Otro problema surge de la restriccin que imponen sobre el lenguaje base. Dicha restriccin es bastante difcil de lograr ya que se deben eliminar elementos de un sistema complejo, donde cada uno tiene su lugar y sus responsabilidades, y estn
www.programemos.com Pgina 20/123

www.programemos.com

coordinados entre s. Tener en cuenta que ya es una tarea compleja el diseo de un lenguaje de programacin, an es ms difcil realizarle cambios a un lenguaje que no fue diseado para esta evolucin. Los lenguajes de propsito general son ms fciles de implementar sobre la base de un lenguaje de programacin existente al no imponer restricciones sobre la base. Tambin tienen el mismo problema de limitar los puntos de enlace a aquellos que pueden ser identificados en el lenguaje base. 2.7 Aspectos en lenguajes procedurales Las razones para utilizar aspectos dentro de los lenguajes procedurales son similares a aquellas para los lenguajes orientados a objetos. Los distintos procedimientos que forman parte del sistema quizs necesiten compartir datos e incluso otros procedimientos, y tambin quizs sea deseable agregarles comportamiento. Se podra pensar que la programacin orientada a objetos solucionara estos problemas, pero como hemos discutido antes, existen conceptos que no son capturados correctamente. Sin utilizar aspectos, los lenguajes procedurales pueden compartir datos y procedimientos a travs del pasaje de parmetros o a travs de un espacio de nombre comn. En los lenguajes estructurados por bloques, el espacio de nombre se particiona en una estructura jerrquica, donde cada bloque tiene visibilidad sobre el(los) bloque (s) que lo contiene(n). Luego, si dos procedimientos Proc1 y Proc2 necesitan acceder a una variable V, entonces V deber declararse en el mismo bloque que Proc1 y Proc2, o en un bloque que contenga a los procedimientos, as como lo muestra el siguiente cdigo: Procedure ProcGlobal; Var V: boolean; Procedure Proc1;{ }; Procedure Proc2;{ }; { };

Sin embargo, el mecanismo de alcance de los lenguajes estructurados por bloques sufre de importantes limitaciones. En el anlisis de Wulf y Shaw sobre los lenguajes estructurados [34] se describen los cuatro problemas ms importantes: Efectos colaterales: pueden definirse como la modificacin del ambiente no local. Estn presentes en la mayora de los lenguajes, ya que deshabilitar todos los posibles
www.programemos.com Pgina 21/123

www.programemos.com

efectos colaterales resulta en un lenguaje muy restrictivo, poco prctico, y de escasa utilidad. Acceso indiscriminado: toda entidad declarada en un bloque, ser siempre visible a los bloques internos, y no hay manera de evitarlo. Vulnerabilidad: puede ser imposible mantener el acceso a una variable, cuando se lo desea. Puede ocurrir cuando un procedimiento P declara una variable V, y tiene un procedimiento interno H que accede a V. Ahora si se inserta entre ellos un procedimiento J, que declara una variable local V (oculta a la variable V declarada en P) entonces H acceder a la variable V declarada en J y no a la declarada en P, que era lo deseado. No se permiten definiciones solapadas: Dados tres procedimientos, P1, P2, y P3, que desean compartir dos variables, V1 y V2 de la siguiente forma: P1 y P2 comparten V1, P2 y P3 comparten V2, P3 no debe acceder a V1, y P1 no debe acceder a V2. Este tipo de relacin es imposible de implementar en un lenguaje estructurado por bloques. Grficamente, se desea modelar el siguiente comportamiento:

Figura 4: Definicin solapada Por lo tanto, es claro que la estructura de bloques no es un mecanismo apropiado para capturar los conceptos entrecruzados debido a los problemas de programacin potenciales que puede ocasionar (acceso indiscriminado y vulnerabilidad), y la imposibilidad de capturar ciertos tipos de conceptos entrecruzados (definiciones solapadas). Luego, es la intencin en [15] que los aspectos se empleen como un mecanismo que extienda las reglas de alcance de los lenguajes procedurales para capturar los conceptos entrecruzados sin la presencia de los problemas anteriormente mencionados. Entonces un aspecto se utiliza como un contenedor para almacenar procedimientos y variables especficas. El acceso a los aspectos es especificado por una palabra clave (accessed by <Lista_Procedimientos>) que determina los nicos procedimientos que pueden acceder a l, sin tener en cuenta el nivel de anidamiento de los mismos. De esta forma, los aspectos solucionan el acceso indiscriminado, la vulnerabilidad y permiten definiciones solapadas, al introducir un nuevo espacio de nombre, que solo es accesible por algunos procedimientos. Por ejemplo, el siguiente cdigo resuelve el problema de definicin solapada:

www.programemos.com Pgina 22/123

www.programemos.com

Aspect A accessed by P1, P2 ; { var V1: boolean; } Aspect B accessed by P2, P3 ; { var V2: boolean; } Procedure P1;{ // puede acceder a V1 y no a V2 } Procedure P2;{ // puede acceder a V1 y a V2 } Procedure P3;{ // puede acceder a V2 y no a V1 } Finalmente, los aspectos descriptos tambin satisfacen las propiedades requeridas en el anlisis de Wulf y Shaw [34] para una solucin alternativa apropiada a las limitaciones de los lenguajes estructurados por bloques: No debe extender el alcance de un nombre a los bloques internos: Se especifica explcitamente los procedimientos que pueden acceder a un aspecto. El derecho de acceso a un nombre tiene que ser de mutuo acuerdo entre el creador y el que accede: se cumple por la misma razn de la propiedad anterior. Los accesos a una estructura y a sus sub-estructuras deben ser independientes: el acceso a una estructura no implica acceder a sus sub-estructuras. Como conclusin, se observa que los aspectos juegan un rol diferente en los lenguajes procedurales que en los lenguajes orientados a objetos. Esto resulta de la diferencias entre los paradigmas, donde los componentes se describen como objetos en uno y como procedimientos en el otro. Al aplicar aspectos a los lenguajes procedurales, los procedimientos tienen conocimiento y dependen de los aspectos, a diferencia de los objetos, que no tienen conocimiento ni dependen de los aspectos.

www.programemos.com Pgina 23/123

www.programemos.com

www.programemos.com Pgina 24/123

www.programemos.com

2.8 Aproximaciones alternativas de aspectos La meta-programacin es la capacidad que tienen los programas de razonar sobre s mismos. Un lenguaje permite la meta-programacin cuando tiene la capacidad de razonar sobre programas escritos en ese lenguaje. Dentro del paradigma funcional se denominan lenguajes meta funcionales, y dentro del paradigma lgico, lenguajes meta lgicos. El paradigma declarativo, que incluye el paradigma funcional y el lgico, permite naturalmente la meta-programacin. Se puede pensar que los aspectos son a la funcionalidad bsica lo que los meta-programas son a los programas: Meta programaci n Aspectos = programas funcionali dad _ bsica Siguiendo este razonamiento surgen dos aproximaciones alternativas para describir aspectos que sern abarcadas a continuacin.
2.8.1 Meta-programacin lgica de aspectos

Se basa en la utilizacin de lenguajes meta lgicos para razonar sobre aspectos, unificando el lenguaje para declarar aspectos con el lenguaje para implementar el tejedor. Los aspectos no son declarados dentro de un lenguaje de aspectos diseado especialmente para tal efecto, sino que son simplemente aserciones lgicas expresadas en un lenguaje lgico general. Estos hechos lgicos funcionan como libros de una librera de reglas lgicas que implementan el tejedor. La principal ventaja de utilizar hechos lgicos para declarar aspectos en vez de un lenguaje de aspectos diseados especialmente es que las declaraciones de aspectos se pueden acceder y declarar por reglas lgicas. Esta tcnica permite al usuario adaptar o extender el lenguaje de aspectos. El programa bsico es representado indirectamente por un conjunto de proposiciones lgicas. Bajo esta aproximacin un tejedor entendera un conjunto de declaraciones para describir aspectos como las que propone Brichau en [31]: introduceMethod(<nombre_de_clase>,{<cdigo_del_mtodo>}): introduce el mtodo <cdigo_del_mtodo> en la clase <nombre_de_clase>. introduceVariable(<nombre_de_clase>,{<variable>}): introduce la variable <variable> en la clase <nombre_de_clase>. adviceBeforeMethod(<nombre_de_clase>,<nombre_del_mtodo>, {<cdigo_agregado>}): agrega <cdigo_agregado> antes del mtodo <nombre_del_mtodo> en la clase <nombre_de_clase>. adviceAfterMethod(<nombre_de_clase>,<nombre_del_mtodo>, { <cdigo_agregado>}): agrega <cdigo_agregado> despus del mtodo <nombre_del_mtodo> en la clase <nombre_de_clase>.
www.programemos.com Pgina 25/123

www.programemos.com

Dado un mdulo de declaraciones el tejedor genera cdigo para todas las declaraciones presentes en dicho mdulo. Esto lo logra generando consultas lgicas para recoger todas las declaraciones mencionadas. Por ejemplo: el siguiente mdulo implementa un aspecto simple de traza. adviceBeforeMethod(claseA,unmtododeA, {system.out.println(`Entrando a claseA.unmtodoA);}). adviceAfterMethod(claseA,unmtododeA, {system.out.println(`Saliendo de claseA.unmtodoA);}). adviceBeforeMethod(claseB,unmtododeB, {system.out.println(`Entrando a claseB.unmtodoB);}). adviceAfterMethod(claseB,unmtododeB, {system.out.println(`Saliendo de claseB.unmtodoB);}). adviceBeforeMethod(claseC,unmtododeC, {system.out.println(`Entrando a claseC.unmtodoC);}). adviceAfterMethod(claseC,unmtododeC, {system.out.println(`Saliendo de claseC.unmtodoC);}).

Tomando ventaja del paradigma lgico podemos evitar la duplicacin de cdigo del mdulo anterior reformulndolo a travs de reglas lgicas:

adviceBeforeMethod(?clase,?unmtodo, {system.out.println(`Entrando a ?clase.?unmtodo);}):-traza(?clase,?unmtodo). adviceAfterMethod(?clase,?unmtodo, {system.out.println(`Saliendo de ?clase.?unmtodo);}):-traza(?clase,?unmtodo). traza(claseA,unmtododeA). traza(claseB,unmtododeB). traza(claseC,unmtododeC). Nota: los identificadores de variables comienzan con un signo de interrogacin. Por ejemplo: ?clase. Las dos primeras declaraciones son reglas lgicas que declaran avisos para cada declaracin de la forma traza(?clase,?unmtodo). Significa que las declaraciones de avisos son vlidas solo si hay declaraciones de trazas. En este proceso, el motor de inferencia lgico liga las variables ?clase y ?unmtodo con las constantes especificadas en las declaraciones de trazas. A travs de este proceso de evaluacin obtenemos el mismo aspecto que antes. Tambin se observa la separacin entre la implementacin del aspecto y el uso del aspecto: las dos primeras reglas son implementadas por el programador del aspecto y las ltimas tres son introducidas por el usuario del aspecto cuando el aspecto se combina con un programa bsico particular.
www.programemos.com Pgina 26/123

www.programemos.com

El verdadero cdigo del aspecto se concentra en las dos primeras reglas mientras que las tres restantes completan los parmetros donde el cdigo de aspecto debe insertarse. Tambin se pueden componer aspectos de una manera directa, aprovechando una vez ms el poder de la lgica. Supongamos que deseamos implementar un nuevo mdulo de aspectos a partir de dos aspectos ya definidos: aspectoA y aspectoB. El nuevo aspecto tendr el comportamiento de A y B en aquellos mtodos que ambos afecten; el comportamiento de A si B no afecta ese mtodo y el comportamiento de B si A no afecta ese mtodo. Contiene las variables y mtodos de ambos aspectos.

introduceMethod(?clase,?cdigomtodo):aspectA.introduceMethod(?clase,?cdigomtodo). introduceMethod(?clase,?cdigomtodo):aspectB.introduceMethod(?clase,?cdigomtodo). introduceVariable(?clase,?variable):aspectA.introduceVariable(?clase,?variable). introduceVariable(?clase,?variable):aspectB.introduceVariable(?clase,?variable). adviceBeforeMethod(?clase,?mtodo,{?codigoA ?codigoB }):aspectA.adviceBeforeMethod(?clase,?mtodo,{?codigoA}) and aspectB.adviceBeforeMethod(?clase,?mtodo,{?codigoB}). adviceBeforeMethod(?clase,?mtodo,{?cdigoA }):aspectA.adviceBeforeMethod(?clase,?mtodo,{?cdigoA}) and not(aspectB.adviceBeforeMethod(?clase,?mtodo,{?cdigoB})). adviceBeforeMethod(?clase,?mtodo,{?cdigoB }):not(aspectA.adviceBeforeMethod(?clase,?mtodo,{?cdigoA})) and aspectB.adviceBeforeMethod(?clase,?mtodo,{?cdigoB}). adviceAfterMethod(?clase,?mtodo,{?cdigoA ?cdigoB }):aspectA.adviceAfterMethod(?clase,?mtodo,{?cdigoA}) and aspectB.adviceAfterMethod(?clase,?mtodo,{?cdigoB}). adviceAfterMethod(?clase,?mtodo,{?cdigoA }):aspectA.adviceAfterMethod(?clase,?mtodo,{?cdigoA}) and not(aspectB.adviceAfterMethod(?clase,?mtodo,{?cdigoB})). adviceAfterMethod(?clase,?mtodo,{?cdigoB }):not(aspectA.adviceAfterMethod(?clase,?mtodo,{?cdigoA})) and aspectB.adviceAfterMethod(?clase,?mtodo,{?cdigoB}). Nota: se introduce el operador de alcance ., para referir a las declaraciones definidas en otros mdulos. Por ejemplo: aspectB.declaracinS especifica que declaracinS se
www.programemos.com Pgina 27/123

www.programemos.com

encuentra definida en el mdulo B. Adems se introduce el orden de la composicin. Esto se refleja en la quinta y sexta regla donde el cdigo de A precede al cdigo de B. Una de las herramientas dentro de esta aproximacin hacia los aspectos es TyRuBa, un lenguaje de meta-programacin lgico para Java. Principalmente fue diseado para generar cdigo Java a partir de descripciones lgicas de la estructura del programa. Fue implementado como parte de la tesis de postgrado de Kris de Volder sobre metaprogramacin lgica orientada a tipos. El acrnimo TyRuBa deriva de TypeRuleBase, que significa basado en reglas con tipos. En pocas palabras, es un lenguaje de programacin lgico con facilidades para la manipulacin de cdigo Java con el propsito de generar cdigo. Para mayor referencia dirigirse a la pgina de TyRuBa [38]. Las ventajas de esta aproximacin provienen del paradigma lgico, porque el programador se concentra en los aspectos y no en cmo estos sern combinados por el tejedor. La combinacin es tarea del proceso de evaluacin. Los aspectos se pueden componer fcilmente, como se vio anteriormente, reduciendo los conflictos entre ellos. En [30] se destacan ventajas tanto para el implementador como para el usuario de aspectos: Los usuarios pueden extender el lenguaje de aspectos on the fly definiendo nuevos tipos de declaraciones de aspectos a partir de las declaraciones existentes. De igual forma el implementador puede definir declaraciones de aspectos en trminos de declaraciones de aspectos de menor nivel. Cabe destacar que la utilizacin de un lenguaje lgico maduro, existente y probado con los aos, resulta en una importante ventaja sobre un lenguaje de aspectos especialmente diseado: el lenguaje lgico puede servir de manera uniforme como formalismo para declarar aspectos como hechos lgicos y como meta-lenguaje para la combinacin como reglas lgicas.
2.8.2 Meta-programacin funcional de aspectos

Se basa en la utilizacin de lenguajes funcionales de alto orden aspectos.

para describir

La meta-programacin funcional es una propuesta general y efectiva para especificar el cdigo de aspectos y el tejedor. Utilizando la terminologa de aspectos se tiene que los componentes son programas funcionales mientras que los aspectos se implementan como transformacin de programas, como se explicar en la seccin 5.2 Trabajos relacionados. El proceso de tejer se considera como una composicin de programas que combina los componentes y los aspectos aplicando las transformaciones a los componentes modeladas por los aspectos [33]. La razn de utilizar meta-programas funcionales radica en la facilidad de verificar propiedades y la naturalidad de los lenguajes funcionales de alto orden para definir manipulaciones abstractas de programas.

www.programemos.com Pgina 28/123

www.programemos.com

Ambas aproximaciones, lgica y funcional, proveen un ambiente adecuado para estudiar e investigar los cimientos tericos del paradigma de la programacin orientada a aspectos[32].

www.programemos.com Pgina 29/123

www.programemos.com

3. Lenguajes orientados a aspectos


A continuacin describiremos informalmente algunos lenguajes orientados a aspectos disponibles actualmente. En la seccin 3.9 estudiaremos con mayor profundidad el lenguaje orientado a aspectos AspectJ, ya que hemos seleccionado este lenguaje por ser la herramienta con mayor usabilidad, futuro, popularidad y desarrollo. 3.1 JPAL La principal caracterstica de esta herramienta es que los puntos de enlace son especificados independientemente del lenguaje base. Estos puntos de enlace independientes reciben el nombre de Junction Point (JP). Por lo tanto la herramienta se llama JPAL que significa Junction Point Aspect Language[20], esto es, Lenguaje de Aspectos basados en JP. Usar programas escritos en JPAL para describir nuevos lenguajes de aspectos facilita para ese lenguaje el desarrollo de tejedores. De hecho, el tejedor JPAL genera un esquema del tejedor de aspectos llamado Esquema del Tejedor. Este esquema tiene un mecanismo que automticamente conecta el cdigo base con los programas de aspectos en puntos de control llamados acciones. El cdigo que agrega el Esquema del Tejedor invoca, cuando es alcanzado en ejecucin, las acciones correspondientes para permitir la ejecucin de los programas de aspectos. Esto permite una vinculacin dinmica con los programas de aspectos, lo cual hace posible modificar en tiempos de ejecucin los programas de aspectos[20]. Sin embargo, esta solucin no es lo suficientemente poderosa como para agregar o reemplazar programas de aspectos en ejecucin. Para tal efecto se agrega al Esquema del Tejedor una entidad llamada Administrador de Programas de Aspectos (APA), el cual puede registrar un nuevo aspecto de una aplicacin y puede llamar a mtodos de aspectos registrados. Es implementado como una librera dinmica que almacena los aspectos y permite dinmicamente agregar, quitar o modificar aspectos, y mandar mensajes a dichos aspectos. La comunicacin entre el Administrador y el Esquema del Tejedor se logra a travs de un Protocolo de Comunicacin entre Procesos que permite registrar aspectos dinmicamente. La siguiente figura resume la arquitectura JPAL: c dig o Esquem a del Tejedor acci ones del
www.programemos.com Pgina 30/123

aspe ctos estt cdigo fuente final A PA

www.programemos.com

Registracin dinmica

de aspect Figura 5: Arquitectura JPAL. El costo de ejecucin de una arquitectura basada en JPAL depende en la implementacin del Administrador de Programas de Aspectos que tiene mayor eficiencia en ambientes interpretados[20]. Resumiendo, JPAL , un descendiente de AspectJ, tiene la particularidad de separar los puntos de enlace, que son independientes del lenguaje base, de sus acciones asociadas que dependen de decisiones de implementacin. Esta separacin permite generar un Esquema de Tejedor para cualquier lenguaje de aspectos. Este esquema ofrece un puente entre el control de la ejecucin y la ejecucin de la accin. Tomando ventaja de esta redireccin se obtiene un modelo de arquitectura para el manejo dinmico de aspectos[20]. Su principal aplicacin es para la implementacin de sistemas distribuidos. 3.2 D D [23] es un ambiente de lenguajes de aspectos para la programacin distribuida. Se llama ambiente de lenguajes, en vez de solamente lenguaje, porque consiste en realidad de dos lenguajes: COOL, para controlar la sincronizacin de hilos(threads), y RIDL, para programar la interaccin entre componentes remotos. Estos dos lenguajes se disearon de manera independiente de un lenguaje componente. Sin embargo establecen un nmero de condiciones sobre el lenguaje componente. El diseo de D es semi-independiente del lenguaje componente, ya que D impone requerimientos sobre el lenguaje componente que satisfacen naturalmente los lenguajes orientados a objetos. Luego el lenguaje componente puede ser cualquiera mientras sea orientado a objetos. Por lo tanto, en teora podra ser implementado con C++, Smalltalk, CLOS, Java o Eiffel. Cristina Lopes, principal diseadora del lenguaje, implement D sobre Java llamando al lenguaje resultante DJ. La sincronizacin es un tem que D captura como un aspecto separado. Por lo tanto las clases no pueden tener cdigo para el control de concurrencia. Un programa puede tener varios hilos concurrentes. La estrategia de sincronizacin por defecto, sin la intervencin de COOL, es que no hay estrategia: en la presencia de mltiples hilos todos los mtodos de todos los objetos pueden ejecutarse concurrentemente. La integracin remota es el otro tem que D captura como un aspecto separado. Luego las clases tampoco pueden tener cdigo para la comunicacin remota. Un programa sin la intervencin de RIDL no es un programa distribuido, la estrategia de comunicacin por defecto es que no hay ninguna estrategia de comunicacin, entonces un programa es distribuido slo si utiliza RIDL. Los mdulos de aspectos pueden acceder a los componentes. Este acceso sin embargo est especificado por un protocolo el cual forma parte del concepto de aspecto. Este
www.programemos.com Pgina 31/123

cdigo ejecut able

www.programemos.com

protocolo puede ser diferente para cada aspecto debido a que diferentes aspectos influyen de maneras diferentes sobre los componentes. En caso de COOL y RIDL los derechos de acceso son idnticos, se les permite inspeccionar al objeto pero no invocar sus mtodos o modificar su estado. Con respecto a la herencia, los mdulos de aspectos se relacionan con la herencia de clases a travs de simples reglas: Sea C una clase y A el mdulo de aspecto asociado a C, se verifican las siguientes propiedades: Visibilidad de campos: Los elementos heredados desde ancestros de C son visibles a A. No hay propagacin de efectos: A no afecta a ninguna superclase de C. Redefinicin de semntica: A redefine completamente cualquier mdulo de aspecto del mismo tipo definido en una superclase de C. No hay ninguna relacin entre A y los mdulos de aspectos de las superclases de C. Herencia de coordinacin: A afecta todas las subclases de C que no tienen asociado un mdulo de aspecto del mismo tipo. A no afecta los nuevos mtodos definidos en una subclase de C. Si un mtodo m declarado en C es redefinido por una subclase de C sin asociarle otro mdulo de aspecto del mismo tipo entonces A tambin es el aspecto para ese mtodo. No es posible para los mdulos de aspectos referir a otro mdulo de aspecto, como consecuencia no es posible establecer ninguna relacin entre los mdulos de aspectos, incluyendo a la herencia.
3.2.1 COOL

COOL (COOrdination aspect Language) es un lenguaje de aspectos de dominio especfico para tratar con la exclusin mutua de hilos, sincronizacin, suspensin y reactivacin de hilos. Un programa COOL consiste de un conjunto de mdulos coordinadores. Los mdulos coordinadores, o directamente coordinadores, se asocian con las clases a travs del nombre. Un mismo coordinador puede coordinar a ms de una clase. La unidad mnima de sincronizacin es el mtodo. La declaracin de un coordinador describe la estrategia de coordinacin. Los coordinadores no son clases: utilizan un lenguaje diferente, no pueden ser instanciados y sirven para un propsito muy especfico. Los coordinadores se asocian automticamente con las instancias de clases que coordinan en tiempo de instanciacin, y durante el tiempo de vida de los objetos esta relacin tiene un protocolo bien definido. Los coordinadores tienen conocimiento de las clases que coordinan para definir la mejor estrategia de coordinacin posible. Sin embargo, las clases no tienen conocimiento de los aspectos, es decir que dentro de una clase no es posible nombrar a un coordinador. La asociacin entre los objetos y los coordinadores es uno-a-uno por defecto y recibe el nombre de coordinacin per object. Sin embargo, un coordinador tambin puede asociarse con todos los objetos de una o ms clases y recibe el nombre de coordinacin per class. Las estrategias de sincronizacin se expresan de forma declarativa.
www.programemos.com Pgina 32/123

www.programemos.com

El cuerpo de un coordinador contiene declaracin de variables de condicin y ordinarias, un conjunto de mtodos auto-exclusivos, varios conjuntos de mtodos mutuamente exclusivos y manejadores de mtodos. Los mtodos nombrados en el cuerpo deben ser mtodos vlidos de las clases coordinadas. Un coordinador asociado a una clase C tiene la siguiente visibilidad: Todos los mtodos pblicos, protegidos y privados de C. Todos los mtodos no privados de las superclases de C. Todas las variables privadas, protegidas y pblicas de C. Todas las variables no privadas de las superclases de C. La siguiente figura describe el protocolo de comunicacin entre un coordinador y un objeto: 1: Dentro de un hilo T, se produce una invocacin al mtodo m del objeto. 2: El pedido es enviado primero al del objeto. 3: El coordinador controla los exclusin y las m. Si alguno de los requerimientos no se satisface, se suspende T. Cuando todas las condiciones se cumplen, T obtiene el derecho m() {... objeto salida. 8: La invocacin del mtodo finalmente retorna. Figura 6: Protocolo de comunicacin de un coordinador en COOL
3.2.2 RIDL

coordinador coordinador requerimientos de precondiciones para el mtodo

de ejecutar el mtodo m. 4: El pedido se envia al objeto. 5: El hilo T ejecuta el mtodo m. 6: Al retornar de la invocacin del mtodo, el resultado se presenta al coordinador. 7: El coordinador ejecuta sus acciones de

RIDL (Remote Interaction and Data transfers aspect Language) es un lenguaje de aspectos de dominio especfico que maneja la transferencia de datos entre diferentes espacios de ejecucin. Un programa RIDL consiste de un conjunto de mdulos de portales. Los mdulos de portales o directamente portales se asocian con las clases por el nombre. Un portal es el
www.programemos.com Pgina 33/123

www.programemos.com

encargado de manejar la interaccin remota y la transferencia de datos de la clase asociada a l, y puede asociarse como mximo a una clase. La unidad mnima de interaccin remota es el mtodo. La declaracin de los portales identifica clases cuyas instancias pueden invocarse desde espacios remotos. Dichas instancias se llaman objetos remotos. La declaracin de un portal identifica qu mtodos de una clase sern exportados sobre la red. En el portal estos mtodos se llaman operaciones remotas. Para cada una de estas operaciones se describe qu objetos remotos esperan y qu datos enviarn a los llamadores. Los portales no son clases: utilizan un lenguaje diferente, no pueden ser instanciados y sirven para un propsito muy especfico. Tampoco son tipos en el sentido estricto de la palabra. Un portal se asocia automticamente con una instancia de la clase en el momento que una referencia a esa instancia se exporta fuera del espacio donde la instancia fue creada. Durante el tiempo de vida de la instancia esta relacin se mantiene mediante un protocolo bien definido. Un portal asociado a una clase C tiene la siguiente visibilidad: Todos los mtodos pblicos, protegidos y privados de C a excepcin de los mtodos estticos. Todos los mtodos no privados de las superclases de C a excepcin de los mtodos estticos. Todas las variables privadas, protegidas y pblicas de todas las clases de una aplicacin D. Este ltimo punto establece una dependencia explcita entre los portales y la relaciones estructurales completas de las clases. Esta dependencia expone la necesidad de controlar la transferencia de datos entre los distintos espacios de ejecucin. A continuacin se describe el protocolo de comunicacin entre un portal y un objeto: 1: Desde un espacio remoto, se produce una portal invocacin al mtodo m del objeto. 2: El pedido es enviado primero al portal del objeto. 3: El mtodo se procesa de acuerdo a su declaracin como operacin remota en el portal: se traen los parmetros del espacio remoto al espacio local segn los modos de pasaje y las directivas de copia declaradas para la operacin remota. 4: El pedido se enva al objeto. 5: El mtodo m se ejecuta. m 6: Al retornar de la invocacin del mtodo, el resultado se presenta al coordinador. objeto 7: El resultado es procesado de acuerdo a su declaracin en la operacin remota.

www.programemos.com Pgina 34/123

www.programemos.com

8: La invocacin del mtodo finalmente retorna, y el resultado es pasado al espacio remoto. Figura 7: Protocolo de comunicacin de un portal en RIDL. Nota: Tanto el objeto como el portal se dividen con las lneas punteadas para representar los manejadores locales y remotos. 3.3 ASPECTC AspectC[27] es un simple lenguaje de aspectos de propsito general que extiende C, es un subconjunto de AspectJ sin ningn soporte para la programacin orientada a objetos o mdulos explcitos. El cdigo de aspectos, conocido como aviso, interacta con la funcionalidad bsica en los lmites de una llamada a una funcin, y puede ejecutarse antes, despus, o durante dicha llamada. Los elementos centrales del lenguaje tienen como objetivo sealar llamadas de funciones particulares, acceder a los parmetros de dichas llamadas, y adherir avisos a ellas. Los cortes en AspectC tomas las siguientes formas: Llamadas a una funcin: call(f(arg)), captura todas las llamadas a la funcin f con un argumento. Durante el flujo de control: cflow(cualquier corte), captura el contexto de ejecucin dinmico del corte. Referencias a una variable: varref(nombre_variable), captura las referencias a la variable nombre_variable. Todos los cortes se pueden describir utilizando expresiones lgicas, aumentando la expresividad del lenguaje: el operador y(&&), el operador o (||), y el operador de negacin(!). Un ejemplo sera: call(f(arg)) || call(h(arg)), con lo cual se captura las llamadas a la funcin f o las llamadas a la funcin g. Como el lenguaje C es de naturaleza esttica, el tejedor de AspectC es esttico. Es interesante contar con esta herramienta de aspectos basada en C, debido a que C es utilizado en numerosas aplicaciones, en especial, aquellas donde la eficiencia es primordial, como por ejemplo, la implementacin de sistemas operativos. Al existir tambin conceptos entrecruzados en la implementacin de sistemas operativos, AspectC pasa a ser la herramienta ideal para tal desarrollo. Un trabajo a mencionar sera el proyecto a-kernel [27], cuya meta es determinar si la programacin orientada a aspectos puede optimizar la modularidad de los sistemas operativos, y reducir as la complejidad y fragilidad asociada con la implementacin de los mismos. 3.4 ASPECTS

www.programemos.com Pgina 35/123

www.programemos.com

AspectS[26] extiende el ambiente Squeak/Smalltalk para permitir un sistema de desarrollo orientado a aspectos. Squeak es una implementacin abierta y portable de Smalltalk-80 cuya mquina virtual est completamente escrita en Smalltalk, para mayor referencia visitar su pgina [38]. Principalmente, AspectS est basado en dos proyectos anteriores: AspectJ de Xerox Parc y el MethodWrappers de John Brant, que es un mecanismo poderoso para agregar comportamiento a un mtodo compilado en Squeak. AspectS, un lenguaje de aspectos de propsito general, utiliza el modelo de lenguaje de AspectJ y ayuda a descubrir la relacin que hay entre los aspectos y los ambientes dinmicos. Soporta programacin en un metanivel, manejando el fenmeno de Cdigo Mezclado a travs de mdulos de aspectos relacionados. Est implementado en Squeak sin cambiar la sintaxis, ni la mquina virtual. En este lenguaje los aspectos se implementan a travs de clases y sus instancias actan como un objeto, respetando el principio de uniformidad. Un aspecto puede contener un conjunto de receptores, enviadores o clases enviadoras. Estos objetos se agregan o se remueven por el cliente y sern usados por el proceso de tejer en ejecucin para determinar si el comportamiento debe activarse o no. En Squeak, la interaccin de los objetos est basada en el paradigma de pasaje de mensajes. Luego, en AspectS los puntos de enlace se implementan a travs de envos de mensajes. Los avisos asocian fragmentos de cdigo de un aspecto con cortes y sus respectivos puntos de enlace, como los objetivos del tejedor para ubicar estos fragmentos en el sistema. Para representar esos fragmentos de cdigo se utilizan bloques(instancias de la clase BlockContext). Los tipos de avisos definibles en AspectS son: Antes y despus de la invocacin a un mtodo (AsBeforeAfterAdvice). Para manejo de excepciones(AsHandlerAdvice). Durante la invocacin de un mtodo(AsAroundAdvice). Un calificador de avisos (AsAdviceQualifier) es usado para controlar la seleccin del aviso apropiado. Es similar al concepto de designadores de cortes de AspectJ. Utiliza un tejedor dinmico que transforma el sistema base de acuerdo a lo especificado en los aspectos. El cdigo tejido se basa en el MethodWrapper y la metaprogramacin. MethodWrapper es un mecanismo que permite introducir cdigo que es ejecutado antes, despus o durante la ejecucin de un mtodo. El proceso de tejer sucede cada vez que una instancia de aspectos es instalada. Para revertir los efectos de un aspecto al sistema, el aspecto debe ser desinstalado. A este proceso se lo conoce como destejer, del ingls unweaving. El tejido de AspectS es completamente dinmico ya que ocurre en ejecucin.

www.programemos.com Pgina 36/123

www.programemos.com

3.5 ASPECTC++ AspectC++[29] es un lenguaje de aspectos de propsito general que extiende el lenguaje C++ para soportar el manejo de aspectos. En este lenguaje los puntos de enlace son puntos en el cdigo componente donde los aspectos pueden interferir. Los puntos de enlaces son capaces de referir a cdigo, tipos, objetos, y flujos de control. Las expresiones de corte son utilizadas para identificar un conjunto de puntos de enlaces. Se componen a partir de los designadores de corte y un conjunto de operadores algebraicos. La declaracin de los avisos es utilizada para especificar cdigo que debe ejecutarse en los puntos de enlace determinados por la expresin de corte. La informacin del contexto del punto de enlace puede exponerse mediante cortes con argumentos y expresiones que contienen identificadores en vez de nombres de tipos, todas las veces que se necesite. Diferentes tipos de aviso pueden ser declarados, permitiendo que el aspecto introduzca comportamiento en diferentes momentos: el aviso despus (after advice), el aviso antes (before advice) y el aviso durante (around advice). Los aspectos en AspectC++ implementan en forma modular los conceptos entrecruzados y son extensiones del concepto de clase en C++. Adems de atributos y mtodos, los aspectos pueden contener declaraciones de avisos. Los aspectos pueden derivarse de clases y aspectos, pero no es posible derivar una clase de un aspecto. La arquitectura del compilador de AspectC++ se muestra en la figura 8. Primero el cdigo fuente de AspectC++ es anlizado lxica, sintctica y semnticamente. Luego se ingresa a la etapa de planificacin, donde las expresiones de corte son evaluadas y se calculan los conjuntos de puntos de enlace. Un plan para el tejedor es creado conteniendo los puntos de enlace y las operaciones a realizar en estos puntos. El tejedor es ahora responsable de transformar el plan en comandos de manipulacin concretos basados en el rbol sintctico de C++ generado por el analizador PUMA. A continuacin el manipulador realiza los cambios necesarios en el cdigo. La salida del manipulador es cdigo fuente en C++, con el cdigo de aspectos tejido dentro de l. Este cdigo no contiene constructores del lenguaje AspectC++ y por lo tanto puede ser convertido en cdigo ejecutable usando un compilador tradicional de C++.

www.programemos.com Pgina 37/123

www.programemos.com

Si bien el manejo de aspectos en AspectC++ es similar al manejo que proporciona AspectJ, introduce modificaciones importantes dentro del modelo de puntos de enlace, permitiendo puntos de enlace sobre clases, objetos, y sobre el flujo de control. Esto resulta en un diseo del lenguaje ms coherente con el paradigma de aspectos. Cdigo fuente en AspectC++ P L ca de na Sint as Asp rbol de sintax Sem sem

Planif

Te comandos del

Mani

Cdig o fuente Compilado

Figura 8: Arquitectura del compilador de AspectC++ 3.6 MALAJ Malaj [24,25] es un sistema que soporta la programacin orientada a aspectos. Define constructores lingsticos separados para cada aspecto de dominio especfico, donde el cdigo de los aspectos tiene una visibilidad limitada del cdigo funcional, reduciendo los posibles conflictos con las caractersticas lingsticas tradicionales y tambin, con el principio de encapsulacin. Malaj es un lenguaje orientado a aspectos de dominio especfico, concentrndose en dos aspectos: sincronizacin y relocacin. Puede verse como un sucesor de los
www.programemos.com Pgina 38/123

www.programemos.com

lenguajes COOL y RIDL por su filosofa, enfatizando la necesidad de restringir la visibilidad de los aspectos, y reglas claras de composicin con los constructores tradicionales. Para cada aspecto, provee un constructor lingstico distinto, limitando as la visibilidad del aspecto sobre el mdulo funcional asociado a l. Esto ltimo se logra al estudiar cuidadosamente la relacin entre el cdigo funcional y un aspecto dado. El lenguaje base de Malaj es una versin restringida de Java, donde se han removido los servicios que proveen los aspectos mencionados. Los servicios removidos son: la palabra clave synchronized, y los mtodos wait, notify, and notifyAll. Para el aspecto de sincronizacin Malaj provee el constructor guardian. Cada guardin es una unidad distinta con su propio nombre, y se asocia con una clase en particular (esto es, vigila esa clase) y expresa la sincronizacin de un conjunto relacionado de mtodos de esa clase, es decir, que el guardin de una clase V representa bsicamente el conjunto de mtodos sincronizados de V. Los guardianes no pueden acceder a los elementos privados de la clase que vigilan, y el acceso a los atributos pblicos y protegidos se limita a un acceso de slo lectura. El comportamiento adicional en un guardin para un mtodo m de la clase asociada se especifica introduciendo cdigo que se ejecutar antes o despus de m, a travs de las clusulas before y after. Una ltima caracterstica de los guardianes es que pueden heredarse. Para reducir el problema de anomala de herencia [10] las clusulas before y after en una clase pueden referirse a las clusulas before y after de su clase padre a travs de la sentencia super. El aspecto de relocacin involucra el movimiento de objetos entre sitios en un ambiente de redes. Este tipo de relacin es claramente dinmico. Para este aspecto Malaj provee el constructor relocator, que llamaremos relocador. Un relocador ser una unidad diferente con su propio nombre, y se asocia con una clase en particular. Las acciones de relocacin pueden ejecutarse antes o despus de la ejecucin de un mtodo. Para modelar este comportamiento, el relocador brinda clusulas before y after, que permiten la especificacin deseada. Tambin la visibilidad del relocator es limitada. Como el constructor guardin, un relocador puede heredarse, y las clusulas before y after en una clase pueden referirse a las clusulas before y after de su clase padre a travs de la sentencia super, y as reducir el impacto de la anomala de herencia[10]. Como conclusin Malaj provee una solucin intermedia entre flexibilidad y poder por un lado, y entendimiento y facilidad de cambio por el otro. No permite describir cualquier aspecto, pero s captura el comportamiento de dos conceptos relacionados con el cdigo funcional. El prximo paso en Malaj es extenderlo para abarcar otros aspectos. 3.7 HYPERJ La aproximacin por Ossher y Tarr sobre la separacin multidimensional de conceptos (MDSOC en ingls) es llamada hyperspaces, y como soporte se construy la herramienta HyperJ[28] en Java.

www.programemos.com Pgina 39/123

www.programemos.com

Para analizar con mayor profundidad HyperJ es necesario introducir primero cierta terminologa relativa a MDSOC : Un espacio de concepto concentra todas las unidades, es decir todos los constructores sintcticos del lenguaje, en un cuerpo de software, como una librera. Organiza las unidades en ese cuerpo de software para separar todos los conceptos importantes, describe las interrelaciones entre los conceptos e indica cmo los componentes del software y el resto del sistema pueden construirse a partir de las unidades que especifican los conceptos. En HyperJ un hiperespacio (hyperspace) es un espacio de concepto especialmente estructurado para soportar la mltiple separacin de conceptos. Su principal caracterstica es que sus unidades se organizan en una matriz multidimensional donde cada eje representa una dimensin de concepto y cada punto en el eje es un concepto en esa dimensin. Los hiperslices son bloques constructores; pueden integrarse para formar un bloque constructor ms grande y eventualmente un sistema completo. Un hipermdulo consiste de un conjunto de hiperslices y conjunto de reglas de integracin, las cuales especifican cmo los hiperslices se relacionan entre ellos y cmo deben integrarse. Una vez introducida la terminologa se puede continuar con el anlisis de HyperJ. Esta herramienta permite componer un conjunto de modelos separados, donde cada uno encapsula un concepto definiendo e implementando una jerarqua de clases apropiada para ese concepto. Generalmente los modelos se superponen y pueden o no referenciarse entre ellos. Cada modelo debe entenderse por s solo. Cualquier modelo puede aumentar su comportamiento componindose con otro: HyperJ no exige una jerarqua base distinguida y no diferencia entre clases y aspectos, permitiendo as que los hiperslices puedan extenderse, adaptarse o integrarse mutuamente cuando se lo necesite. Esto demuestra un mayor nivel de expresividad para la descripcin de aspectos en comparacin con las herramientas descriptas anteriormente. Existe una versin prototipo de HyperJ que brinda un marco visual para la creacin y modificacin de las relaciones de composicin, permitiendo un proceso simple de prueba y error para la integracin de conceptos en el sistema. El usuario comienza especificando un hipermdulo eligiendo un conjunto de conceptos y un conjunto tentativo de reglas de integracin. HyperJ crea hiperslices vlidos para esos conceptos y los compone basndose en las reglas que recibe. Luego el hiperslice resultante se muestra en pantalla, si el usuario no est conforme puede en ese momento introducir nuevas reglas o modificar las reglas existentes y as continuar este proceso de refinacin hasta obtener el modelo deseado.

www.programemos.com Pgina 40/123

www.programemos.com

3.8 Tabla comparativa de las herramientas En la siguiente tabla se encuentran resumidas las principales caractersticas de las herramientas orientadas a aspectos descriptas en las secciones anteriores: Leng. OA JPAL Leng. Base Independiente Tejido Dinmico Propsito General Caractersticas salientes Meta-Tejedor. Independiente del leng. base. Totalmente dinmico. Usado en la programacin distribuida. Provee interaccin entre aspectos y herencia. Describe la sincronizacin de hilos concurrentes. Visibilidad limitada del aspecto. Modulariza la interaccin remota. Visibilidad limitada del aspecto. Usado en la implementacin orientada a aspectos de sistemas operativos. Basado en el paradigma de pasaje de mensajes. Todo aspecto es un objeto. Aspectos son extensiones del concepto de clase. Descripcin ms natural de los puntos de enlace.

Cualquier lenguaje OO

Esttico

Especfico

COOL

Cualquier lenguaje OO

Esttico

Especfico

RIDL

Cualquier lenguaje OO

Esttico

Especfico

AspectC

Esttico

General

AspectS

Squeak

Dinmico

General

AspectC++

C++

Esttico

General

www.programemos.com Pgina 41/123

www.programemos.com

Modulariza los aspectos de sincronizacin y relocacin. Su objetivo es eliminar los conflictos entre POA y POO. HyperJ Java Dinmico General Basado en hyperslices. Permite la composicin de aspectos. Ambiente visual de trabajo. Tabla 2: Comparacin entre herramientas orientadas a aspectos. Como lo refleja la tabla anterior las tres decisiones de diseo: lenguaje base, tejido y propsito, son totalmente independientes entre s para los LOA. Esto es, que todas las combinaciones entre las decisiones son tericamente posibles. Aunque existe la tendencia a implementar el comportamiento del tejedor segn la naturaleza del lenguaje base: si el lenguaje base es esttico entonces el tejedor es esttico y si el lenguaje base es dinmico entonces el tejedor es dinmico. Hasta donde conocemos nadie ha afrontado la tarea de desarrollar un nuevo lenguaje base. Se han tomado lenguajes bases existentes a los cuales se los restringe en algunos casos, como en los lenguajes de dominio especfico, y en otros se los utiliza sin modificaciones.

MALAJ

Java

Dinmico

Especfico

www.programemos.com Pgina 42/123

www.programemos.com

3.9 AspectJ AspectJ [35] es un lenguaje orientado a aspectos de propsito general, cuya primera versin fue lanzada en 1998 por el equipo conformado por Gregor Kickzales (lder del proyecto), Ron Bodkin, Bill Griswold, Erik Hilsdale, Jim Hugunin, Wes Isberg y Mik Kersten. La versin que analizamos en este trabajo es la versin actual a la fecha (Junio de 2002) AspectJ 1.0.4; es importante hacer esta aclaracin porque continuamente surgen nuevas versiones que mejoran la calidad final. Es una herramienta que est en desarrollo y las nuevas versiones pueden tanto corregir errores de su versin predecesora como modificar el lenguaje. AspectJ es una extensin compatible de Java para facilitar el uso de aspectos por parte de los programadores de Java. Por compatible se entiende: Compatibilidad base: todos los programas vlidos de Java deben ser programas vlidos de AspectJ. Compatibilidad de plataforma: todos los programas vlidos de AspectJ deben correr sobre la mquina virtual estndar de Java. Compatibilidad de programacin: la programacin en AspectJ debe ser una extensin natural de la programacin en Java. Esta ltima meta fue una de las guas ms importante a la hora de tomar decisiones sobre el lenguaje. Es estticamente tipado y usa el sistema de tipos esttico de Java. Extiende Java para soportar el manejo de aspectos agregando a la semntica de Java cuatro entidades principales. Esto se ve reflejado en la figura 9. Los puntos de enlace son puntos bien definidos en la ejecucin de un programa, entre ellos podemos citar llamadas a mtodos y accesos a atributos. Los cortes agrupan puntos de enlace y permiten exponer el contexto en ejecucin de dichos puntos. Existen cortes primitivos y tambin definidos por el usuario. Los avisos son acciones que se ejecutan en cada punto de enlace incluido en un corte. Los avisos tienen acceso a los valores expuestos por el corte. Las tres entidades anteriores son dinmicas porque permiten definir comportamiento adicional que actuar en tiempo de ejecucin. Las introducciones y declaraciones permiten cambiar la estructura de clases de un programa agregando o extendiendo interfaces y clases con nuevos atributos, constructores o mtodos. Esta ltima entidad es esttica porque afecta la signatura esttica del programa. Obtenemos entonces que AspectJ soporta tanto implementacin esttica como dinmica de conceptos entrecruzados. Un aspecto es un tipo entrecruzado que encapsula cortes, avisos y las propiedades estticas. Por tipo se entiende una unidad modular de cdigo con una interface bien definida sobre la cual es posible razonar en tiempo de compilacin.
www.programemos.com Pgina 43/123

www.programemos.com

LOA

BASE

ASPECTOS Entidades dinmicas Puntos de enlace Cortes Avisos Introducciones y Declaraciones

AspectJ =

Java

+ Entidades estticas

Figura 9: AspectJ es una extensin de Java para el manejo de aspectos. Existen otras metas en la investigacin del paradigma POA que AspectJ no tiene intencin de abarcar. No es una traduccin purista de los conceptos del paradigma, tampoco es un clculo formal de aspectos ni tampoco representa un esfuerzo agresivo para explorar las posibilidades de un lenguaje orientado a aspectos. La intencin de AspectJ es ser un LOA prctico, que provea un conjunto slido y maduro de caractersticas orientadas a aspectos, compatible con Java para aprovechar su popularidad.

www.programemos.com Pgina 44/123

www.programemos.com

4. Referencia AspectJ
Desde esta gua de referencia de AspectJ se pretende dar una visin general del lenguaje. Se explica cada una de las palabras clave que lo comprende, y se acompaa de pequeos ejemplos que ilustran el funcionamiento del mismo. 4.1 Aspects Formato general: [privileged] [Modifiers] aspect Id [extends Type] [implements TypeList] [PerClause] donde PerClause es uno de los siguientes: pertarget(Pointcut) perthis(Pointcut) percflow(Pointcut) percflowbelow(Pointcut) issingleton Un aspecto se declara de forma similar a una clase. Es la unidad de cdigo que encapsula los puntos de cortes, avisos, introducciones y declaraciones, adems de sus propios mtodos y atributos. La diferencia con una clase es que un aspecto puede entrecruzar otras clases o aspectos, y que no se puede crear una instancia con una expresin new, proceso de clonado o serializacin. Un aspecto puede incluir la definicin de un constructor, pero dicha definicin no debe contener argumentos y no debe sealar excepciones chequeadas. Un aspecto puede ser definido en un paquete, o como un aspecto interno, esto es, puede ser miembro de una clase, una interface u otro aspecto. Se puede declarar un aspecto abstracto, que posteriormente puede ser extendido por otro aspecto. Existen algunas situaciones donde es necesario para los aspectos acceder a recursos privados o protegidos de otras clases. Para permitir esto se puede declarar al aspecto como privilegiado (privileged). Un aspecto privilegiado puede acceder a todos los atributos y mtodos, incluso a los privados Nada mejor para entender el significado de las palabras claves, que usar algn ejemplo para su mejor comprensin.

www.programemos.com Pgina 45/123

www.programemos.com

4.1.1 Aspect

Indica que vamos a definir un aspecto.


Ejemplo 1. aspect public class Test { public void Say(String name) { System.out.println(name); } public static void main(String[] args) { Test test = new Test(); test.Say("Hello"); System.out.println("She say - "); test.Say("bye"); } } public aspect Pensando { pointcut speak() : call(public void Say(String)); before() : speak() { System.out.println("Before Say - Think"); } after() : speak() { System.out.println("After Say - Smile"); } }

Resultado: Before Say - Think Hello After Say - Smile She say Before Say - Think bye After Say - Smile

Explicacin: se ha definido el Aspecto Pensando, en el que antes de llamar al mtodo Say se indicar que se tiene que pensar lo que se va a decir y en el que despus de llamar al mtodo Say se indicara que ya solo se puede sonreir. Equivalencia Formato General: Modifiers aspect Id { ... public aspect Pensando { ...
www.programemos.com Pgina 46/123

www.programemos.com

4.1.2 extends, implements

Un aspecto puede extender una clase, u otro aspecto abstracto y puede implementar tantos interfaces como se le indiquen. La siguientes son unas reglas a tener en cuenta: De un aspecto a pesar de extender una clase no se puede crear una instancia del mismo con el mtodo new. Una clase no puede extender un aspecto. Un aspecto no puede extender un aspecto que no sea abstracto.

El cdigo escrito en un aspecto est sujeto a las mismas reglas de acceso del cdigo Java para referenciar a miembros de clases o aspectos.

www.programemos.com Pgina 47/123

www.programemos.com

Ejemplo 2. extends, implements public class Test { public void Say(String name) { System.out.println(name); } public static void main(String[] args) { Test test = new Test(); test.Say("Hello"); System.out.println("She say - "); test.Say("bye"); } } public class Repensando { public void OrSay(String name) { System.out.println(name); } } public aspect Pensando extends Repensando { pointcut ifSpeak() : call(public void OrSay(String)); pointcut speak() : call(public void Say(String)); before() : speak() { OrSay("ehhmmmm"); System.out.println("Before Say - Think"); } after() : speak() { System.out.println("After Say - Smile"); } before() : ifSpeak() { System.out.println("What I Say?"); } }

www.programemos.com Pgina 48/123

www.programemos.com

Resultado: What I Say? ehhmmmm Before Say - Think Hello After Say - Smile She say What I Say? ehhmmmm Before Say - Think bye After Say - Smile

Explicacin: se ha definido el Aspecto Pensando que extiende la clase Repensando. Tal y como se puede ver en el Advice 'before() : speak()' se hace uso del mtodo que se haba definido en la clase Repensando. Tambin se ha definido un Advice 'before() : ifSpeak()' que ejecutar el cdigo incluido en el mismo antes del Pointcut definido para el mtodo OrSay. Equivalencia Formato General: Modifiers aspect Id extends Type public aspect Pensando extends Repensando
4.1.3 pertarget, perthis

La asociacin de un aspecto por objeto, permite que un aspecto pueda mantener un determinado estado para cada objeto. Por defecto la instancia de un aspecto es compartida por todos los objetos. Por lo tanto si se define una variable dentro del aspecto y se le asigna un valor, este valor es compartido para cada instancia de la clase que haga uso de l a travs del aspecto. pertarget: mantiene una instancia del aspecto para el objeto del punto de unin definido en el punto de corte(Pointcut) indicado dentro de la sentencia pertarget. perthis: mantiene una instancia del aspecto para el objeto con la ejecucin del punto de unin definido en el punto de corte (Pointcut) de la sentencia perthis. La instancia del Aspecto se inicia la primera vez que se ejecuta el punto de unin definido en el Pointcut, y se mantiene durante la vida del objeto.

www.programemos.com Pgina 49/123

www.programemos.com

Ejemplo 3. perthis, pertarget public class Test { public static void main(String[] args) { CurrentObject co1 = new CurrentObject(); CurrentObject co2 = new CurrentObject(); co1.Method("co1", "xxx"); co1.Function(); co2.Method("co2", "yyy"); co2.Function(); co1.Method("co1", "xxz"); co1.Function(); } }

Con la clase Test se va a probar que hay varias instancias del Aspecto perthisAspect.
Ejemplo 3. perthis, pertarget public class CurrentObject { private String _name; private String _state; public void Method (String name, String state) { _name=name; _state=state; System.out.println("Execute " + name + ".Method"); } public void SetState(String state){ _state=state; } public String GetState(){ return _state; } public String Function(){ System.out.println("Execute " + _name + ".Function"); return _state; } }

La clase CurrentObject va ha permitir realizar la prueba para capturar los puntos de unin que se desean. En este caso se va a capturar la ejecucin del mtodo Method y la funcin Function.

www.programemos.com Pgina 50/123

www.programemos.com

Ejemplo 3. perthis, pertarget public aspect perthisAspect perthis(pointBeforeMethod()) { String _state; perthisAspect() { System.out.println("Create New Instance Aspect"); } pointcut pointBeforeMethod() : execution(void CurrentObject.Method(String, String)); pointcut pointAfterMethod(CurrentObject obj) : execution(void CurrentObject.Method(String, String)) && this(obj); pointcut pointFunction(CurrentObject obj) : execution(* CurrentObject.Function()) && this(obj); before() : pointBeforeMethod() { System.out.println("Before Method "); } after(CurrentObject obj) : pointAfterMethod(obj) { if (_state==null) {_state=obj.GetState();} System.out.println("Set State Aspect After Method " + _state + "\n"); } after(CurrentObject obj) : pointFunction(obj) { System.out.println("Get State Aspect After Function " + _state + "\n"); } } Resultado: What I Say? ehhmmmm Before Say - Think Hello After Say - Smile She say What I Say? ehhmmmm Before Say - Think bye After Say - Smile

Explicacin: con el Aspecto perthisAspect se define que se quiere crear una instancia del aspecto para el objeto del punto de unin(Join Point) que define el punto de corte (Pointcut). En este caso la instancia del Aspecto se crea con la ejecucin del mtodo Method de la clase CurrentObject a travs del punto de ejecucin (Advice) "before() : pointBeforeMethod()". Con el Advice "after(CurrentObject obj) : pointAfterMethod(obj)" se establece el estado del Aspecto con el valor que contiene el objeto obj.GetState().

www.programemos.com Pgina 51/123

www.programemos.com

obj es el objeto del punto de unin Method que se expresa en el pointcut pointAfterMethod. Por ltimo se recupera el estado del Aspecto una vez se ejecuta la funcin function ya que se ha definido un punto de ejecucin (Advice) para punto de corte(Pointcut) que captura su ejecucin. Equivalencia Formato General: Modifiers aspect Id perthis(Pointcut) public aspect perthisAspect perthis(pointBeforeMethod())
4.1.4 percflow, percflowbelow

La asociacin de un aspecto por flujo, establece que se crea un aspecto para cada punto de unin definido en el punto de corte. Para que se entienda mejor, cada vez que se llame al punto de unin se crear una instancia del aspecto. percflow: crea una instancia del aspecto cada vez que se ejecute el punto de unin definido en punto de corte. percflowbelow: crea una instancia del aspecto cada vez que se ejecute bajo el punto de corte. Los puntos de ejecucin (Advice) no tendrn efecto sobre el Pointcut definido.
Ejemplo 4. percflow, percflowbelow public class Test { public static void main(String[] args) { Margarita flor = new Margarita(); int _Numero=5; flor.SetNumeroHojas(_Numero); System.out.println("Quedan " + flor.GetNumeroHojas() + " hojas"); for(int i = 3 ; i < _Numero ; i++) { flor.QuitarHoja(); } System.out.println("Quedan " + flor.GetNumeroHojas() + " hojas"); } }

Para evaluar cuando se crean las instancias se va ha utilizar la clase Margarita que va a permitir deshojarla.

www.programemos.com Pgina 52/123

www.programemos.com

Ejemplo 4. percflow, percflowbelow public class Margarita { private int _NumeroHojas; Margarita(){ _NumeroHojas=5; } public void SetNumeroHojas(int NumeroHojas){ _NumeroHojas=NumeroHojas; } public int GetNumeroHojas(){ return _NumeroHojas; } public void QuitarHoja(){ _NumeroHojas--; } }

La clase Margarita permite indicar cuantas hojas tiene la margarita, a la vez que permite quitarle hojas a la misma.
Ejemplo 4. percflow, percflowbelow public aspect deshojar percflow(QuitarHojita(Margarita)) { deshojar() { System.out.println("New Instancia"); } pointcut QuitarHojita(Margarita Flor) : (execution(* Margarita.QuitarHoja()) && this(Flor)); before(Margarita Flor) : QuitarHojita(Flor) { if (Flor.GetNumeroHojas()%2==0) { System.out.println("No me quiere.."); } else{ System.out.println("Me quiere.."); } } }

Por ltimo se ha definido un Aspecto para que ayude a cada uno en la difcil tarea de saber de si su amor le quiere o no le quiere. Debido a la importancia del Aspecto se ha decidido crear una instancia del aspecto cada vez que se quite una hoja a la margarita, ya que no debe afectar el cambio de estado de otras clases.

www.programemos.com Pgina 53/123

www.programemos.com

Resultado: Quedan 5 hojas New Instancia Me quiere.. New Instancia No me quiere.. Quedan 3 hojas

Equivalencia Formato General: Modifiers aspect Id perClause public aspect deshojar percflow(QuitarHojita(Margarita))
4.1.5 issingleton

Por defecto todos los aspectos salvo que se indique lo contrario crean una instancia nica del Aspecto, compartida para todos las clases que lancen los Pointcut y Advice del aspecto. El Aspecto definido en el Ejemplo 1 es issingleton aunque no se haya indicado. El motivo de querer escribir la sentencia issingleton en la declaracin de un Aspecto es querer cambiar el comportamiento de otro Aspecto abstracto extendido. Equivalencia Formato General: Modifiers aspect Id issingleton public aspect deshojar issingleton

www.programemos.com Pgina 54/123

www.programemos.com

4.2 Pointcut definitions Formato general: abstract [Modifiers] pointcut Id (Formals) ; [Modifiers] pointcut Id (Formals) : Pointcut ; Un punto de corte permite definir la seleccin de puntos de unin(Join Point) dentro de un Aspecto. Los cortes principalmente son usados por los avisos y pueden ser compuestos con operadores booleanos para crear otros cortes.
4.2.1 private pointcut Id() : call([ModifiersPat] TypePat [TypePat.].IdPat(TypePat | .., ...));

Define un punto de corte definido como privado. Slo es accesible dentro del propio Aspecto.
4.2.2 pointcut Id(Type param) : set([ModifiersPat] [TypePat.] new (TypePat | .., ...)) [throws ThrowsPat];

Define un punto de corte visible dentro del package que expone un tipo de dato.
4.2.3 public abstract pointcut Id();

Define un punto de corte abstracto, que puede ser referenciado desde cualquier aspecto. Un aspecto que extienda un aspecto abstracto con el punto de corte definido abstracto debe implementar dicho punto de corte abstracto.
4.2.4 abstract pointcut Id(Object o);

Define un punto de corte abstracto, que puede ser utilizado por otro aspecto que extienda el aspecto abstracto que lo define, dentro del mismo package. ModifiersPat: private, public, protected TypePat: nombre de un tipo definido (int, String, boolean, nombre de una clase, ...) La clase Test va a permitir realizar una prueba para entender lo que son los puntos de corte (Pointcut).

www.programemos.com Pgina 55/123

www.programemos.com

Ejemplo 5. pointcut public class Test { public static void main(String[] args) { Expediente expte = new Expediente(); expte.abrirExpediente("1235813"); expte.setEmailCliente("mail@tucorreo.com"); System.out.println("Test - Expediente: " + expte.getNumeroExpediente () + " de " + expte.getEmailCliente()); System.out.println("Test - Es buen cliente: " + expte.saldoCliente()); expte.cerrarExpediente(); Expediente expte2 = new Expediente(); expte2.abrirExpediente("213455"); expte2.setEmailCliente("mlorente@programemos.com", "Mariano Lorente"); System.out.println("Test - Expediente: " + expte2.getNumeroExpediente () + " de " + expte2.getEmailCliente()); System.out.println("Test - Nombre: " + expte2.getNombreCliente()); System.out.println("Test - Es buen cliente: " + expte2.saldoCliente()); expte2.cerrarExpediente(); } }

La clase expediente y la clase correo son las que van ha proporcionar los puntos de unin (Join Point) que van a capturar los puntos de corte (Pointcut).

www.programemos.com Pgina 56/123

www.programemos.com

Ejemplo 5. pointcut public class Expediente { private String _numero; private String _emailCliente; private String _nombre; String getNumeroExpediente() { return _numero; } void setNumeroExpediente(String numero) { _numero=numero; } String getEmailCliente() { return _emailCliente; } void setEmailCliente(String email) { _emailCliente=email; } void setEmailCliente(String email, String nombre) { _emailCliente=email; _nombre=nombre; } String getNombreCliente() { return _nombre; } void setNombreCliente(String nombre) { _nombre=nombre; } void abrirExpediente(String numero) { _numero=numero; System.out.println("Expediente - Abriendo el expediente " + _numero); } void cerrarExpediente() { System.out.println("Expediente - Cerrando el expediente " + _numero); } boolean saldoCliente() { System.out.println("Expediente - esBuenCliente"); return false; } } public class Correo { public void enviarCorreo(String email) { System.out.println("Correo - Enviando correo al buzon " + email +
www.programemos.com Pgina 57/123

www.programemos.com

Se ha creado el Aspecto ProcesarCorreo que va ha permitir examinar las distintas declaraciones que se pueden realizar de los puntos de corte.

www.programemos.com Pgina 58/123

www.programemos.com

Ejemplo 5. pointcut public aspect ProcesarCorreo extends Correo{ pointcut CierreExpediente(Expediente obj) : (execution(void Expediente.cerrarExpediente()) && this(obj)); pointcut TratamientoNombre(String campo) : set(private String _nombre) && args(campo); pointcut ValidarCorreo(String email) : call(* Expediente.setEmailCliente(..)) && args(email); private pointcut ValidarCliente() : call(* Expediente.saldoCliente());

pointcut ValidarCorreoNombre(String email, String nombre) : call (* Expediente.setEmailCliente(..)) && args(email, nombre); after(Expediente obj) : CierreExpediente(obj) { enviarCorreo(obj.getEmailCliente()); } before(String campo) : TratamientoNombre(campo) { campo="D. " + campo; System.out.println("ProcesarCorreo - " + campo); } void around(String email) : ValidarCorreo(email) { System.out.println("Validando correo " + email); proceed("to: " + email); } void around(String email, String nombre) : ValidarCorreoNombre(email, nombre) { System.out.println("Validando correo " + email + " " + nombre); proceed("to: " + email, nombre); } boolean around() : ValidarCliente() { Expediente expte = (Expediente)thisJoinPoint.getTarget(); System.out.println("Validando Cliente"); if (expte.getEmailCliente().indexOf("tucorreo.com")>0) { return true; } else { return false; } } }

www.programemos.com Pgina 59/123

www.programemos.com

Resultado: Expediente - Abriendo el expediente 1235813 Validando correo mail@tucorreo.com Test - Expediente: 1235813 de to: mail@tucorreo.com Validando Cliente Test - Es buen cliente: true Expediente - Cerrando el expediente 1235813 Correo - Enviando correo al buzon to: mail@tucorreo.com Expediente - Abriendo el expediente 213455 Validando correo mlorente@programemos.com Mariano Lorente ProcesarCorreo - D. Mariano Lorente Test - Expediente: 213455 de to: mlorente@programemos.com Test - Nombre: Mariano Lorente Validando Cliente Test - Es buen cliente: false Expediente - Cerrando el expediente 213455 Correo - Enviando correo al buzon to: mlorente@programemos.com

Explicacion: lo primero que se ve en la declaracin del aspecto "public aspect ProcesarCorreo extends Correo" es que extiende la clase correo, para poder utilizar su funcionalidad. 1. Pointcut pointcut CierreExpediente(Expediente obj) : (execution(void Expediente.cerrarExpediente()) && this(obj)); En este punto de corte se pretende capturar la ejecucin del mtodo cerrarExpediente de la clase Expediente, al mismo tiempo que se pretende acceder a la instancia sobre la que se captura el mtodo. execution(void Expediente.cerrarExpediente(): capturamos la ejecucin del mtodo cerrarExpediente. this(obj): captura la instancia. A la instancia se podr acceder en los punto de ejecucin (advice) que se declaren para el punto de corte. &&: este operador sirve para que el punto de corte (Pointcut) capture tanto la ejecucin del mtodo como la instancia del objeto. 2. Pointcut pointcut TratamientoNombre(String campo) : args(campo);

set(private String _nombre) &&

Este punto de corte se pretende capturar la escritura sobre una variable privada de la clase Expediente. set(private String _nombre): captura la escritura en la variable.

www.programemos.com Pgina 60/123

www.programemos.com

args(campo): da acceso al valor de la variable. Esta declaracin va en consonancia al siguiente cdigo pointcut TratamientoNombre(String campo) ya que el argumento que expondr el punto de corte se captura con la sentencia args. &&: este operador sirve para unir con la condicin 'Y' los distintos puntos de unin que se han indicado en el punto de corte. En este caso capturar la escritura en la variable y el valor de la misma. 3. Pointcut pointcut ValidarCorreo(String email) : call(* Expediente.setEmailCliente(..)) && args (email); Punto de corte que captura la ejecucin del mtodo setEmailCliente a la vez que captura el rgumento que va ha recibir. call(* Expediente.setEmailCliente(..)): en esta sentencia se captura la llamada al mtodo setEmailCliente independientemente del nmero de argumentos que reciba este mtodo, esto se indica con (..), de esta forma si el mtodo est sobrecargado se podr capturar la llamada al mtodo. args(email): indica que se capture el primer argumento que reciba el mtodo setEmailCliente. &&: este operador sirve para unir con la condicin 'Y' los distintos puntos de unin que se han indicado en el punto de corte. En este caso la llamada al mtodo setEmailCliente y la captura del argumento que reciba en primer lugar. 4. Pointcut private pointcut ValidarCliente() :

call(* Expediente.saldoCliente());

En este caso el punto de corte se ha definido private, con esto se quiere evitar que se pueda hacer uso de l en otro aspecto que pueda extender el presente. call(* Expediente.saldoCliente()): en esta sentencia se captura el punto de unin saldoCliente de la clase Expediente. Se puede ver que despus de la sentencia call ( aparece un *, que sirve para indicar que capture la llamada al mtodo indicado independientemente del modificador utilizado. El modificador de un mtodo puede ser private, public, protected. 5. Pointcut pointcut ValidarCorreoNombre(String email, String Expediente.setEmailCliente(..)) && args(email, nombre);

nombre)

call

(*

Este punto de corte es similar al que se ha definido en el punto 3, con la diferencia que se pretende capturar el valor de los dos parmetros que puede tener el mtodo

www.programemos.com Pgina 61/123

www.programemos.com

setEmailCliente. Para ello hay que obtener los parmetros con la sentecia args(email, nombre) y definir en el punto de corte tambin la misma cantidad de parmetros. Si en el punto de corte se definen menos parmetros que en la sentencia args, se obtendr el valor para aquellos que se comparta en la definicin. Si la sentencia se hubiera definido de la siguiente manera, en el Advice solo se tendra acceso al valor que del parmetro nombre. Figura 1. pointcut ValidarCorreoNombre(String nombre) : call (* Expediente.setEmailCliente (..)) && args(email, nombre);

www.programemos.com Pgina 62/123

www.programemos.com

4.3 Comodines y operadores del pointcut Los comodines y operadores que pueden utilizarse en los puntos de corte (pointcut), sirven para seleccionar los puntos de unin que va ha capturar el punto de corte. * Sirve para sustituir a un conjunto de caracteres, exceptuando el punto. .. Sirve para sustituir a un conjunto de parmetros. + Realiza la bsqueda de puntos de unin dentro del package o subpackage ! Permite seleccionar todos los puntos de unin (join point) excepto el indicado. || Permite unir un conjunto de puntos de corte (pointcut) con la condicin del uno o el otro. && Permite unir un conjunto de puntos de corte (pointcut) con la condicin del uno y el otro.

www.programemos.com Pgina 63/123

www.programemos.com

4.4 Primitive Pointcuts La primitiva de puntos de cortes sirve para poder definir la captura de los distintos puntos de unin que pueden interesar. La nomenclatura seguida es la siguiente: MethodPat: [ModifiersPat] TypePat [TypePat].IdPath(TypePat | .., ...) [throws ThrowsPat] ConstructorPat: [ModifiersPat] [TypePat.] new (TypePat | .., ...) [throws ThrowsPat] FieldPat: [ModifiersPat] TypePat [TypePat.] IdPat TypePat: IdPat [+] [[]...] !TypePat TypePat && TypePat TypePat || TypePat (TypePat)

www.programemos.com Pgina 64/123

www.programemos.com

4.4.1 call(MethodPat), call(ConstructorPat)

Captura la llamada a un mtodo o constructor de una clase.


4.4.2 execution(MethodPat), execution(ConstructorPat)

Captura la ejecucin de un mtodo o constructor. En el siguiente ejemplo se demuestra las particularidades de las primitivas call y execution.
Ejemplo 6. call, execution
public class Test { public static void main(String[] args) { Tercero oTercero = new Tercero(); oTercero.setNombre("Tercero"); oTercero.setNIF("1235813"); oTercero.setDireccion("Direccin Tercero"); oTercero.enviarCorreo(); System.out.println("Fin Tercero\n\n"); Cliente oCliente = new Cliente(); oCliente.setNombre("Cliente"); oCliente.setNIF("21344579"); oCliente.setDireccion("Direccin Cliente"); oCliente.setEmail("cliente@programemos.com"); oCliente.enviarCorreo(); System.out.println("Fin Cliente\n\n"); Acreedor oAcreedor = new Acreedor(); oAcreedor.setNombre("Acreedor"); oAcreedor.setNIF("124203327"); oAcreedor.setDireccion("Direccin Acreedor"); oAcreedor.setEmail("acreedor@programemos.com"); oAcreedor.enviarCorreo(); System.out.println("Fin Acreedor\n\n"); Tercero oAcreedorTercero = oAcreedor; oAcreedorTercero.enviarCorreo(); System.out.println("Fin Acreedor\n\n"); } }

La clase Test sirve para poder establecer el sistema de pruebas a utilizar.

www.programemos.com Pgina 65/123

www.programemos.com

Ejemplo 6. call, execution public class Tercero { private String _nombre; private String _nif; private String _direccion; public String getNombre() { return _nombre; } public void setNombre(String valor) { _nombre=valor; } public String getNIF() { return _nif; } public void setNIF(String valor) { _nif=valor; } public String getDireccion() { return _direccion; } public void setDireccion(String valor) { _direccion=valor; } public void enviarCorreo() { System.out.println("Nombre: " + _nombre + "\nDireccin: " + _direccion); } }

La clase Tercero va ha ser la clase base que vamos a utilizar para poder extender con las clases Cliente y Acreedor otras.

www.programemos.com Pgina 66/123

www.programemos.com

Ejemplo 6. call, execution public class Cliente extends Tercero { private String _email; public String getEmail() { return _email; } public void setEmail(String valor) { _email=valor; enviarCorreo(); } }

La clase Cliente extiende la clase Tercero e implementa dos mtodos nuevos.


Ejemplo 6. call, execution public class Acreedor extends Tercero //Cliente { private String _email; public String getEmail() { return _email; } public void setEmail(String valor) { _email=valor; } public void enviarCorreo() { System.out.println("Nombre: " + getNombre() + "\nEmail: " + _email); } }

Con la clase Acreedor se extiende en un primer momento la clase Tercero y posteriormente la clase Cliente. A su vez esta clase sobre escribe el mtodo enviarCorreo y tambin sobre escribe los mtodos getEmail y setEmail si extiende la clase Cliente en vez de la clase Tercero.

www.programemos.com Pgina 67/123

www.programemos.com

Ejemplo 6. call, execution import org.aspectj.lang.*; import org.aspectj.lang.reflect.*; public aspect Traza { boolean HePasadoPorAqui=false; pointcut TrazaCallNombre() : call(* *.setNombre(String)); //&& withincode(* *.setNombre(String)); pointcut TrazaExecuteNombre() : execution(* *.setNombre(String)); //&& withincode(* *.setNombre(String)); pointcut TrazaCallEmail() : call(* *.setEmail(String)); pointcut TrazaExecuteEmail() : execution(* *.setEmail(String)); pointcut TrazaCallEnviarCorreo() : call(* *.enviarCorreo()); pointcut TrazaExecuteEnviarCorreo() : execution(* *.enviarCorreo()); before () :TrazaCallNombre() { System.out.println("call setNombre -----------------------" + ++contar); escribirComentario(thisJoinPoint); if (HePasadoPorAqui==false) { HePasadoPorAqui=true; Tercero oTercero=(Tercero)thisJoinPoint.getTarget(); oTercero.setNombre("Don " + oTercero.getNombre()); } } before () :TrazaExecuteNombre() { System.out.println("execution setNombre -----------------------" + ++contar); escribirComentario(thisJoinPoint); if (HePasadoPorAqui==false) { HePasadoPorAqui=true; Tercero oTercero=(Tercero)thisJoinPoint.getTarget(); oTercero.setNombre("Don " + oTercero.getNombre()); } } before () :TrazaCallEmail() { System.out.println("call setEmail -----------------------" + ++contar); escribirComentario(thisJoinPoint); } before () :TrazaExecuteEmail() { System.out.println("execution setEmail -----------------------" + ++contar); escribirComentario(thisJoinPoint); } before () :TrazaCallEnviarCorreo() { System.out.println("call enviarCorreo -----------------------" + ++contar); escribirComentario(thisJoinPoint); } before () :TrazaExecuteEnviarCorreo() { System.out.println("execution enviarCorreo -----------------------" + ++contar); escribirComentario(thisJoinPoint);
www.programemos.com Pgina 68/123

www.programemos.com

Por ltimo el aspecto Traza permite poder seguir el orden de las llamadas.

www.programemos.com Pgina 69/123

www.programemos.com

Resultado: call setNombre -----------------------1 This: null toLongString: call(public void ejemplo_6.Tercero.setNombre(java.lang.String)) getThis: null getTarget: ejemplo_6.Tercero@cf2c80 call setNombre -----------------------2 This: ejemplo_6.Traza@1729854 toLongString: call(public void ejemplo_6.Tercero.setNombre(java.lang.String)) getThis: ejemplo_6.Traza@1729854 getTarget: ejemplo_6.Tercero@cf2c80 execution setNombre -----------------------3 This: ejemplo_6.Tercero@cf2c80 toLongString: execution(public void ejemplo_6.Tercero.setNombre(java.lang.String)) getThis: ejemplo_6.Tercero@cf2c80 getTarget: ejemplo_6.Tercero@cf2c80 execution setNombre -----------------------4 This: ejemplo_6.Tercero@cf2c80 toLongString: execution(public void ejemplo_6.Tercero.setNombre(java.lang.String)) getThis: ejemplo_6.Tercero@cf2c80 getTarget: ejemplo_6.Tercero@cf2c80 call enviarCorreo -----------------------5 This: null toLongString: call(public void ejemplo_6.Tercero.enviarCorreo()) getThis: null getTarget: ejemplo_6.Tercero@cf2c80 execution enviarCorreo -----------------------6 This: ejemplo_6.Tercero@cf2c80 toLongString: execution(public void ejemplo_6.Tercero.enviarCorreo()) getThis: ejemplo_6.Tercero@cf2c80 getTarget: ejemplo_6.Tercero@cf2c80 Nombre: Tercero Direccin: Direccin Tercero Fin Tercero call setNombre -----------------------7 This: null toLongString: call(public void ejemplo_6.Cliente.setNombre(java.lang.String)) getThis: null getTarget: ejemplo_6.Cliente@10385c1 execution setNombre -----------------------8 This: ejemplo_6.Cliente@10385c1 toLongString: execution(public void ejemplo_6.Tercero.setNombre(java.lang.String)) getThis: ejemplo_6.Cliente@10385c1 getTarget: ejemplo_6.Cliente@10385c1 call setEmail -----------------------9
www.programemos.com Pgina 70/123

www.programemos.com

Explicacin: en el siguiente cdigo se ha creado unos puntos de corte para capturar la llamada y ejecucin del mtodo setNombre. pointcut TrazaCallNombre() : call(* *.setNombre(String)); //&& withincode(* *.setNombre(String)); pointcut TrazaExecuteNombre() : execution(* *.setNombre(String)); //&& withincode(* *.setNombre(String)); Se puede observar que al final de los puntos de corte hay cdigo comentado que nos servir para evaluar el comportamiento que sufre el programa al quitar los comentarios. Para estos puntos de cortes, se han definido unos Puntos de ejecucin (advice), que los capture.
before () :TrazaCallNombre() { System.out.println("call setNombre -----------------------" + ++contar); escribirComentario(thisJoinPoint); if (HePasadoPorAqui==false) { HePasadoPorAqui=true; Tercero oTercero=(Tercero)thisJoinPoint.getTarget(); oTercero.setNombre("Don " + oTercero.getNombre()); } } before () :TrazaExecuteNombre() { System.out.println("execution setNombre -----------------------" + ++contar); escribirComentario(thisJoinPoint); if (HePasadoPorAqui==false) { // Este cdigo slo se ejecutar cuando se quite el comentario de los puntos de corte. HePasadoPorAqui=true; Tercero oTercero=(Tercero)thisJoinPoint.getTarget(); oTercero.setNombre("Don " + oTercero.getNombre()); } }

El primer cambio evidente entre ambos advice se puede obtener al comprobar el contexto de la llamada. Esto se puede conseguir tal y como se muestra en lnea siguiente: System.out.println("getThis: " + PuntoUnion.getThis()); Se puede observar que el resultado del Advice de la llamada obtiene distinto resultado del Advice de la ejecucin. En el primer caso el resultado es getThis: null y en el segundo getThis: ejemplo_6.Tercero@cf2c80. Esto quiere decir que en primer caso no se tiene acceso al objeto que realiza la llamada y en el segundo si se tiene acceso al objeto que realiz la llamada. S la llamada se hace desde un objeto se puede acceder a su contexto como pasa cuando en la Clase Cliente en el mtodo setEmail si se llama al mtodo enviarCorreo (Ver call enviarCorreo -----------------------11).
www.programemos.com Pgina 71/123

www.programemos.com

S la llamada se realiza desde un aspecto se puede acceder tambin a su contexto si se declara el punto de corte como sigue: (Ver execution setNombre -----------------------1 execution setNombre -----------------------2) pointcut TrazaCallNombre() : call(* *.setNombre(String)) && withincode(* *.setNombre(String)); pointcut TrazaExecuteNombre() : execution(* *.setNombre(String)) && withincode(* *.setNombre(String)); El resultado es que no se captura ninguna llamada al mtodo setNombre y solo se captura su ejecucin, por que el mtodo ya se est ejecutando y no realiza la llamada. withincode: captura la ejecucin dentro del mtodo o constructor indicado. Para entender mejor ver la siguiente figura.
Figura 2.
call(* *.setNombre(String)); +---------------------------------------------+ | public static void main(String[] args) { | | Tercero oTercero = new Tercero(); | oTercero.setNombre("Tercero"); | ... +---------------------------------------------+

| | | ----> Punto de unin de la | LLamada

+---------------------------------------------+ | public class Tercero { | | | | ... | | public void setNombre(String valor) { | | _nombre=valor; ----> Punto de unin de la | } | interrupcin del cdigo | ... | +---------------------------------------------+ execution(* *.setNombre(String)); +---------------------------------------------+ | public class Tercero { | | | | ... | | public void setNombre(String valor) { ----> Punto de unin de la | | LLamada | _nombre=valor; ----> Punto de unin de la | } | | | interrupcin del cdigo | ... | +---------------------------------------------+

www.programemos.com Pgina 72/123

www.programemos.com

Por norma general se debe utilizar call para capturar la llamada actual a un mtodo o constructor, en contraposicin a execution que se utiliza para capturar la ejecucin dentro de un punto de unin.
4.4.3 This(TypePat)

Captura todos los puntos de enlace donde el objeto actual (el objeto ligado a this) es una instancia de una clase que coincide con el Patrn de Clase, o es instancia de una clase que coincide con la clase asociada al identificador.
4.4.4 Target (TypePat)

Captura todos los puntos de enlace donde el objeto objetivo (el objeto sobre el cual se invoca un mtodo o una operacin de atributo) es una instancia de una clase que coincide con el Patrn de Clase, o es instancia de una clase que coincide con la clase asociada al identificador.
4.4.5 Args(TypePat)

Captura todos los puntos de enlace donde los argumentos son instancias de una clase que coincide con el Patrn de Clase o con la clase del identificador. Si es un Patrn de Clase entonces el argumento en esa posicin debe ser instancia de una clase que coincida con el Patrn de Clase. Si es un identificador entonces el argumento en esa posicin debe ser instancia de una clase que coincida con la clase asociada al identificador.
4.4.6 initialization(ConstructorPat)

Captura la creacin de una instancia que utilice el constructor indicado.


4.4.7 preinitialization(ConstructorPat)

Captura la creacin de una instancia que utilice el constructor indicado antes de que el constructor super sea llamado.
4.4.8 staticinitialization(TypePat)

Captura el constructor de una clase esttica. Tenemos la clase de Test, la clase Tercero y la clase Cliente que extiende a la clase Tercero.

www.programemos.com Pgina 73/123

www.programemos.com

Ejemplo 7. initialization, preinitialization


public class Test { public static void main(String[] args) { Tercero oTercero = new Tercero(); oTercero.setNombre("Tercero"); System.out.println("Fin Tercero\n\n"); Cliente oCliente = new Cliente(); oCliente.setNombre("Cliente"); oCliente.setNIF("1235813"); System.out.println("Fin Cliente\n\n"); } } public class Tercero { private String _nombre; private String _nif; private String _direccion; public Tercero(){ System.out.println("Constructor Tercero"); } public String getNombre() { return _nombre; } public void setNombre(String valor) { _nombre=valor; } } public class Cliente extends Tercero { String _nif; public Cliente() { super(); System.out.println("Constructor Cliente");} public String getNIF() { return _nif;} public void setNIF(String valor) { _nif=valor; } }

Para probar las primitivas preinitialization y initialization se va a utilizar un Aspecto que nos muestre el orden en que se ejecutan dichas primitivas al aplicarlas en los puntos de corte.

www.programemos.com Pgina 74/123

www.programemos.com

Ejemplo 7. initialization, preinitialization public aspect Constructores { pointcut ConstructorPreInicializacion(): preinitialization(Cliente.new()); pointcut ConstructorInicializacion(): initialization(Cliente.new()); before () : ConstructorPreInicializacion() { System.out.println("Constructor Pre-Inicializacin"); } before () : ConstructorInicializacion() { System.out.println("Constructor Inicializacin"); } } Resultado: Constructor Tercero Fin Tercero Constructor Pre-Inicializacin Constructor Tercero Constructor Inicializacin Constructor Cliente Fin Cliente

Explicacion: lo primero que se puede observar es que lo puntos de cortes que se han definido son para capturar el constructor de la clase Cliente y no hay ningn tipo de corte que captura el constructor de la clase Tercero. En el momento que se ejecuta el siguiente cdigo Cliente oCliente = new Cliente() lo primero que sucede es que salta el punto de corte ConstructorPreInicializacion esto provoca la salida en la consola de Constructor Pre-Inicializacin, seguidamente se ejecuta la llamada al constructor de la superclase al ejecutarse super en el constructor del cliente: public Cliente() { super(); System.out.println("Constructor Cliente"); } Esto provoca la salida en consola Constructor Tercero, despus de ejecutarse el constructor de la clase tercero, se lanzar el punto de corte ConstructorInicializacion que provacar la salida en consola de Constructor Cliente. Estas son las diferencias entre preinitialization y initialization, as que podremos hacer uso de ellas segn sea la necesidad del momento.
4.4.9 get(FieldPat)

Captura la lectura de una variable de una clase.


www.programemos.com Pgina 75/123

www.programemos.com

4.4.10 set(FieldPat)

Captura la escritura en una variable de una clase. En este ejemplo se captura la lectura y escritura sobre una variable privada declarada en una clase. Como en el resto de ejemplos se va crear una clase Test para realizar la prueba y en este caso se va utilizar la clase Clave que permite almacenar y borrar valores de un Vector. Aparte proporciona un mtodo para poder obtener el nmero de elementos que contiene esta clase.
Ejemplo 8, get, set public class Test { public static void main(String[] args) { Clave oClave=new Clave(); oClave.nuevaClave("Primera"); oClave.nuevaClave("Segunda"); oClave.nuevaClave("Tercera"); oClave.borraClave(2); oClave.borraClave(1); oClave.borraClave(0); } } public class Clave { private Vector _clave=new Vector(); public void nuevaClave(String valor) { System.out.println("nuevaClave " + valor); _clave.addElement(valor); } public void borraClave(int posicion) { System.out.println("borraClave " + (String)_clave.elementAt(posicion)); _clave.removeElementAt(posicion); } public int dameNumeroElementos() { return _clave.size(); } }

El aspecto que vamos a aplicar a la clase Clave es el siguiente:

www.programemos.com Pgina 76/123

www.programemos.com

Ejemplo 8, get, set import java.util.Vector; public aspect AspectClave { pointcut setVector(Vector valor) : set(private Vector Clave._clave) && args(valor); pointcut getVector() : get(private Vector Clave._clave) && !withincode(int Clave.dameNumeroElementos()); before(Vector valor) : setVector(valor) { System.out.println("Tamao vector set: " + valor.size()); } before() : getVector() { Clave objeto = (Clave)thisJoinPoint.getThis(); System.out.println("Tamao vector get: " + objeto.dameNumeroElementos()); } } Resultado: Tamao vector set: 0 nuevaClave Primera Tamao vector get: 0 nuevaClave Segunda Tamao vector get: 1 nuevaClave Tercera Tamao vector get: 2 Tamao vector get: 3 borraClave Tercera Tamao vector get: 3 Tamao vector get: 2 borraClave Segunda Tamao vector get: 2 Tamao vector get: 1 borraClave Primera Tamao vector get: 1

Explicacin: tal y como se puede apreciar los dos puntos de cortes definidos para set y get se utilizan en combinacin con otras primitivas. En el primer punto de corte set(private Vector Clave._clave) && args(valor) se ha decidido capturar la escritura en la variable privada _clave de la clase Clave, pero en este punto de corte tambin se ha definido que se quiere obtener el valor de dicha variable y para ello se ha utilizado args(valor), para poder pasar el valor al punto de ejecucin(Advice) en el punto de corte se ha declarado la variable tal y como sigue pointcut setVector(Vector valor). En el segundo punto de corte get(private Vector Clave._clave) && !withincode(int Clave.dameNumeroElementos()) se captura la lectura que se haga de la variable privada _clave de la clase Clave. A su vez se ha utilizado la primitiva !withincode(int Clave.dameNumeroElementos()) para excluir que la lectura que se realiza de la variable _clave de la clase Clave desde el mtodo dameNumeroElementos. Hay que recordar que ! es un operador de negacin y que withincode permite capturar el cdigo que se ejecuta dentro del mtodo que se defina.
www.programemos.com Pgina 77/123

www.programemos.com

4.4.11 handler(TypePat)

Captura el manejador de una excepcin. En el siguiente ejemplo se puede comprobar como se puede usar.
Ejemplo 9, handler
public class Test { public static void main(String[] args) { Ordenador ordenador=new Ordenador(); System.out.println("Test: resultado 50/2 - " + ordenador.divide(50, 2)); System.out.println("Test: resultado 50/0 - " + ordenador.divide(50, 0)); System.out.println("Test: resultado 50/4 - " + ordenador.divide(50, 4)); } }

La clase ordenador permite realizar la divisin de dos nmeros. En el caso que el divisor sea 0 se producir una excepcin. El manejador de esta excepcin se puede capturar con la primitiva handler.
Ejemplo 9, handler public class Ordenador { int divide(int a, int b) { try { return a / b; } catch (ArithmeticException e) { System.out.println("Ordenador: divide.catch"); return 0; } } }

El aspecto que se ha definido, permite capturar el manejador de un determinado tipo de excepcin mediante el punto de corte erroresOperaciones, dando a su vez acceso a la excepcin. Tambin se captura cualquier excepcin que se produzca mediante el punto de corte todosErrores.

www.programemos.com Pgina 78/123

www.programemos.com

Ejemplo 9, handler public aspect AspectError { pointcut erroresOperaciones(ArithmeticException e) : handler (ArithmeticException) && args(e); pointcut todosErrores() : handler(Exception+); before(ArithmeticException e) : erroresOperaciones(e) { System.out.println("AspectError: Colega es que no sabes que no se puede dividir por 0."); System.out.println("AspectError: Mensaje - " + e.getMessage()); } before() : todosErrores() { System.out.println("AspectError: Me temo que hubo un error."); } } Resultado: Test: resultado 50/2 - 25 AspectError: Colega es que no sabes que no se puede dividir por 0. AspectError: Mensaje - / by zero AspectError: Me temo que hubo un error. Ordenador: divide.catch Test: resultado 50/0 - 0 Test: resultado 50/4 - 12

Al ejecutar el programa se ha obtenido el siguiente resultado. Se puede comprobar que se ha capturado el manejador de la excepcin y que se tiene acceso a la propia excepcin. Hay que mencionar que en el punto de corte pointcut todosErrores() : handler (Exception+) es donde de indica que se capture el manejador de Exception y todos los manejadores que controlen los que deriven de Exception.
4.4.12 adviceexecution()

Captura la ejecucin de todos los puntos de consulta (Advice), y cuando se dice de todos, es de todos. Su uso debe ser en compaa de otras primitivas para aplicarlo donde se desee. Al ejemplo 9 se le ha aadido un nuevo aspecto que captura la ejecucin de todos los advices.

www.programemos.com Pgina 79/123

www.programemos.com

Ejemplo 9, adviceexecution public aspect AspectAdvices { pointcut ptadvices() : adviceexecution() && !within(AspectAdvices); before() : ptadvices() { System.out.println("Ejecucin de " + thisJoinPoint.getSignature()); } }

Tal y como se puede apreciar se ha creado un nuevo aspecto, en vez de aadir el cdigo nuevo al aspecto ya existente AspectError. La causa de hacer esto es evitar que se cree un bucle recursivo infinito, debido a que adviceexecution captura todas las ejecuciones de los advices. En !within(AspectAdvices) evitamos que capture la ejecucin de su propio advice, cosa que hubiera sido imposible si se hubiera codificado en el aspecto AspectError.
4.4.13 withincode(ConstructorPat)

Captura un punto de unin que se ejecute dentro del paquete, clase o mtodo definido. Las primitivas winthincode, within estn pensadas para ser utilizados en colaboracin con otras primitivas.
Ejemplo 8, withincode import java.util.Vector; public aspect AspectClave { pointcut setVector(Vector valor) : set(private Vector Clave._clave) && args (valor); pointcut getVector() : get(private Vector Clave._clave) && !withincode(int Clave.dameNumeroElementos()); before(Vector valor) : setVector(valor) { System.out.println("Tamao vector set: " + valor.size()); } before() : getVector() { Clave objeto = (Clave)thisJoinPoint.getThis(); System.out.println("Tamao vector get: " + objeto.dameNumeroElementos()); } }

En el ejemplo 8 se ha hecho uso de withincode para excluir las lecturas de una variable privada siempre y cuando se ejecutarn dentro del mtodo dameNumeroElementos.

www.programemos.com Pgina 80/123

www.programemos.com

4.4.14 within(TypePat)

Captura un punto de unin que se ejecute dentro del paquete o clase definida. Si en el ejemplo 8 se sustituye withincode por within(clave), excluir la lectura de una determinada variable privada, siempre y cuando fuera el acceso se realizase desde la clase clave. El nuevo resultado sera el siguiente:
Resultado: nuevaClave Primera Tamao vector get: 0 nuevaClave Segunda Tamao vector get: 1 nuevaClave Tercera Tamao vector get: 2 Tamao vector get: 3 borraClave Tercera Tamao vector get: 3 Tamao vector get: 2 borraClave Segunda Tamao vector get: 2 Tamao vector get: 1 borraClave Primera Tamao vector get: 1

4.4.15 Cflow(Pointcut)

Captura todos los puntos de enlace en el flujo de control de los puntos de enlace capturados por el corte pasado como parmetro.
4.4.16 Cflowbelow(Pointcut)

Captura todos los puntos de enlace en el flujo de control debajo de los puntos de enlace capturados por el corte pasado como parmetro, sin incluir el punto de enlace inicial del flujo de control.
4.4.17 If()

Captura todos los puntos de enlace cuando la expresin booleana se satisface.

www.programemos.com Pgina 81/123

www.programemos.com

4.5. Join Point Un punto de unin es la parte de un programa que es susceptible de ser capturada por un punto de corte. A continuacin de definen los Join Points que son susceptible de ser capturados. Tipo de Join Point. Ejecucin de un mtodo Llamada a un mtodo Ejecucin de un constructor Llamada a un constructor Inicializacin de una clase Inicializacin de una clase esttica Lectura de un atributo Escritura de un atributo Ejecucin de una manipulador de Excepcin Inicializacin de un objeto Pre-inicializacin de un objeto Ejecucin de un punto de ejecucin Sintaxis del Pointcut execution(MethodSignature) call(MethodSignature) execution(ConstructorSignature) call(ConstructorSignature) initialization(TypeSignature) staticinitialization(TypeSignature) get(FieldSignature) set(FieldSignature) handler(TypeSignature) initialization(ConstructorSignature) preinitialization (ConstructorSignature) adviceexecution()

Ejecucin de un mtodo: Cuando el cuerpo de un mtodo se ejecuta. Llamada a un mtodo: Cuando un mtodo es invocado, no incluye llamadas a super. Ejecucin de un constructor: Cuando se ejecuta el cdigo de un constructor, despus de su llamada al constructor this o super. Llamada a un constructor: Cuando un objeto es creado y un constructor es invocado, sin incluir la llamada al constructor this o super. Inicializacin de una clase: Cuando los contructores no estticos de una clase se ejecutan. Incializacin de una clase esttica: Cuando se ejecuta el contructor esttico para una clase. Lectura de un atributo: Cuando se referencia a un atributo no final. Un atributo final es un atributo que no cambia su valor una vez inicializado. Escritura de un atributo: Cuando se realiza la asignacin a un atributo. Ejecucin de un manipulador de Excepcin: Cuando el manejador de una excepcin se ejecuta. Inicializacin de un objeto: Cuando el cdigo del contructor de una clase particular se ejecuta. Comprende el tiempo entre el retorno del constructor de su clase padre y el
www.programemos.com Pgina 82/123

www.programemos.com

retorno de la llamada a su primer constructor. Incluye todos los inicializadores dinmicos y constructores usados para crear el objeto. Pre-inicializacin de un objeto: Antes que el cdigo del constructor de una clase particular se ejecute. Comprende el tiempo entre el comienzo de la llamada al primer constructor y el comienzo del constructor de su clase padre. Luego, la ejecucin de estos puntos de enlace comprenden los puntos de enlace del cdigo encontrado en las llamadas a constructores this y super. Ejecucin de un punto de ejecucin: captura la ejecucin de un punto de ejecucin. 4.6. Advice declarations Permite declarar un aviso para un determinado punto de corte. La ejecucin del aviso depende del tipo del mismo. Esto puede ser despus del punto de corte, antes o durante la ejecucin del punto de corte. Formato general: [strictfp] AdviceSpec [throws TypeList] : Pointcut { Body } donde AdviceSpec es uno de los siguientes: before (Formals) after (Formals) after (Formals) returning [ (Formal) ] after (Formals) throwing [ (Formal) ] Type around (Formals)
4.6.1 Before(Formals):

Define un aviso(Advice) antes de la ejecucin del punto de unin(Point cut). Ejemplos que se pueden encontrar en el manual:
Ejemplo 1. Before bsico. pointcut speak() : call(public void Say(String)); before() : speak() { System.out.println("Before Say - Think"); }

En el Ejemplo 1 se puede ver un ejemplo bsico de definicin de un Advice Before.

www.programemos.com Pgina 83/123

www.programemos.com

Ejemplo 4. Before que contiene como parmetro el objeto del punto de unin. pointcut QuitarHojita(Margarita Flor) : (execution(* (Flor)); before(Margarita Flor) : QuitarHojita(Flor) { if (Flor.GetNumeroHojas()%2==0) { System.out.println("No me quiere.."); } else{ System.out.println("Me quiere.."); } } Margarita.QuitarHoja()) && this

En el Ejemplo 4 se puede observar una definicin ms compleja ya que admite parmetros. En Este caso el Advice recibe como parmetro el objeto que contiene el punto de unin definido en el punto de corte.
pointcut QuitarHojita(Margarita Flor) : (execution(* Margarita.QuitarHoja()) && this (Flor));

Este punto de corte captura la ejecucin del punto de unin QuitarHoja de la clase Margarita y captura el objeto del punto de unin que en este caso es Flor. Como se puede apreciar Flor es del tipo Margarita. S el punto de corte define un parmetro, el Advice tiene que capturar el parmetro definido por el punto de corte. Hecho esto, tendr acceso a dicho parmetro.
before(Margarita Flor) : QuitarHojita(Flor) Ejemplo 5. Before que contiene como parmetro un campo privado. pointcut TratamientoNombre(String campo) : set(private String _nombre) && args (campo); before(String campo) : TratamientoNombre(campo) { campo="D. " + campo; System.out.println("ProcesarCorreo - " + campo); }

Este ejemplo es similar al ejemplo 4, con la diferencia que el parmetro capturado no es el objeto del punto de unin, sino una variable privada llamada _nombre.

www.programemos.com Pgina 84/123

www.programemos.com

Ejemplo 9. Before que contiene como parmetro una excepcin. pointcut erroresOperaciones(ArithmeticException e) : handler(ArithmeticException) && args(e); before(ArithmeticException e) : erroresOperaciones(e) { System.out.println("AspectError: Colega es que no sabes que no se puede dividir por 0."); System.out.println("AspectError: Mensaje - " + e.getMessage()); }

En el ejemplo 9 se ha definido un punto de corte que captura el manejador de una excepcin y la propia excepcin. El Advice se hace eco del parmetro que recibe que en este caso es una excepcin.
4.6.2 after (Formals)

Define un punto de ejecucin(Advice) despus de la ejecucin del punto de unin (Point cut). Ejemplos que se pueden encontrar en el manual:
Ejemplo 1. After bsico.
pointcut speak() : call(public void Say(String)); after() : speak() { System.out.println("After Say - Smile"); }

Ejemplo bsico de un Advice After. Tambin se poda haber escrito de la siguiente manera.
after() : call(public void Say(String)) { System.out.println("After Say - Smile"); }

www.programemos.com Pgina 85/123

www.programemos.com

Ejemplo 3. After que contiene como parmetro el objeto del punto de unin. pointcut pointAfterMethod(CurrentObject obj) : execution(void CurrentObject.Method (String, String)) && this(obj); pointcut pointFunction(CurrentObject obj) : execution(* CurrentObject.Function()) && this(obj); before() : pointBeforeMethod() { System.out.println("Before Method "); } after(CurrentObject obj) : pointAfterMethod(obj) { if (_state==null) {_state=obj.GetState();} System.out.println("Set State Aspect After Method " + _state + "\n"); } after(CurrentObject obj) : pointFunction(obj) { System.out.println("Get State Aspect After Function " + _state +"\n"); }

En el ejemplo 3 se han definido dos puntos de cortes que capturan las ejecucin de un mtodo y una funcin a la vez que capturan el objeto del punto de unin. La definicin del Advice After debe hacerse igual que en la definicin de los Advice Before.

4.6.3 after (Formals) returning [ (Formal) ]

A veces interesa que se ejecute un Advice siempre y cuando la ejecucin del punto de corte no genere una excepcin, en este se debe declarar el Advice como sigue. Modifiquemos el Ejemplo 1.
Ejemplo 1. After returning. pointcut speak() : call(public void Say(String)); after() returning: speak() { System.out.println("After Say - Smile"); }

Tal como queda ahora el ejemplo, el Advice se ejecutar siempre y cuando el mtodo Say no provoque una excepcin.
4.6.4 after (Formals) throwing [ (Formal) ]

www.programemos.com Pgina 86/123

www.programemos.com

Despus de leer el Advice anterior es fcil llegar a la conclusin de que en algunas interesar captura un punto de corte siempre y cuando el punto de corte provoque una excepcin. Si se toma otra vez el Ejemplo 1 y se modifica, quedara de la siguiente manera:
Ejemplo 1. After throwing. pointcut speak() : call(public void Say(String)); after() throwing: speak() { System.out.println("After Say - Smile"); }

Tal como queda ahora el ejemplo, el Advice se ejecutar siempre y cuando el mtodo Say provoque una excepcin.
4.6.5 Type around (Formals)

Define un Advice que tiene la capacidad de reemplazar el punto de corte completamente, o modificar el valor de los parmetros que recibe el punto de unin. En el Ejemplo 5 hay definidos varios Advices:
Ejemplo 5. Advice que modificar el valor de los parmetros del punto de unin. pointcut ValidarCorreo(String email) : call(* Expediente.setEmailCliente(..)) && args (email); void around(String email) : ValidarCorreo(email) { System.out.println("Validando correo " + email); proceed("to: " + email); }

En este primero se ha definido un punto de corte que captura la llamada al mtodo setEmailCliente de la clase Expediente y el argumento email que recibe. En el Advice cuando se llama a proceed("to: " + email); se ejecuta el punto de unin capturado por el punto de corte, pero ahora en vez de recibir como parmetro el contenido del parmetro email, recibe to: concatenado a parmetro email.

www.programemos.com Pgina 87/123

www.programemos.com

Ejemplo 5. Advice que reemplaza el cdigo del punto de corte por el definido en el mismo Advice. private pointcut ValidarCliente() : call(* Expediente.saldoCliente());

boolean around() : ValidarCliente() { Expediente expte = (Expediente)thisJoinPoint.getTarget(); System.out.println("Validando Cliente"); if (expte.getEmailCliente().indexOf("tucorreo.com")>0) { return true; } else { return false; } }

En este Advice se reemplaza el cdigo del mtodo saldoCliente de la clase Expediente, por el propio cdigo del Advice.

www.programemos.com Pgina 88/123

www.programemos.com

5. Conclusiones finales
La POA es un paradigma que recin est naciendo. Todava queda mucho por hacer e investigar, como por ejemplo: obtener mtricas formales que sirvan para cuantificar la utilidad de la POA; analizar cmo aplicar aspectos en las otras etapas del ciclo de vida del software: en el anlisis, en el diseo2, en el testing y en la documentacin; investigar sobre la formalizacin de los aspectos3; observar cmo es la integracin de los aspectos con las aproximaciones, mtodos, herramientas y procesos de desarrollo existentes; desarrollar herramientas orientadas a aspectos que respeten los principios de diseo; entre otras reas de investigacin. Estamos en el comienzo de un nuevo paradigma, descubriendo su potencialidad, sus problemas, y las posibles soluciones. A medida que se logre avanzar en la investigacin se irn obteniendo conceptos cada vez ms slidos. De esta manera, la POA ir creciendo, madurando como paradigma, y enfrentndose a las debilidades que surjan. Los resultados encontrados en la bibliografia y los que hemos obtenido en este trabajo son ms que prometedores y nos hacen pensar que la POA es una de las ramas con mayor futuro dentro de la ingeniera de software. En el resto de esta ltima seccin se compara el paradigma de aspectos con su predecesor, el paradigma de objetos y se analiza la relacin entre ellos. Tambin se menciona algunas reas de investigacin relacionadas con el paradigma teniendo en cuenta que sus avances influirn en el futuro de la POA. Por ltimo, se enuncian lo que segn nuestro anlisis son las mayores ventajas y desventajas de la POA. 5.1 Breve comparacin entre POA y POO A primera vista dara la impresin que la POA y la POO son en realidad el mismo paradigma. Sin embargo, esta primera impresin es errnea. Un anlisis ms profundo revela las diferencias entre los paradigmas: A travs de la POO los sistemas toman la forma de un conjunto de objetos que colaboran entre s. En realidad, la mayor fortaleza de la POO se demuestra cuando hay que modelar conceptos comunes. Sin embargo, falla al modelar los conceptos que se entrecruzan. POA logra este objetivo al tratar los conceptos entrecruzados como elementos de primera clase, extrayndolos horizontalmente de la estructura vertical del rbol de herencia. Tanto la POA como la POO crean implementaciones modularizadas y con mnimo acoplamiento. La diferencia radica en qu mientras la POA se enfoca en los conceptos que se entrecruzan, la POO se enfoca en los conceptos comunes y los ubica en un rbol de herencia. Grficamente esto se ve reflejado en la figura 12.

2 3

Ver referencias [5,43,44,45,46]. Ver referencias [47,48,49].


www.programemos.com Pgina 89/123

www.programemos.com

POO: conceptos comunes POA: conceptos entrecruzados Clase A

Clase A1 atri atri mt

Clase A2 atri asp ecto asp ecto

mt mt

Figura 12: Comparacin de POA con POO. En POA la implementacin de los conceptos son independientes. Esta independencia la distingue de las tcnicas inherentes a la POO. En POA, el flujo de composicin va desde de los conceptos que se entrecruzan al concepto principal; mientras que en la POO el flujo va en direccin opuesta. Otra de las impresiones errneas que puede tener quien lee por primera vez sobre aspectos es considerar que la POA est limitada a utilizar como base a la POO. Entonces es primordial aclarar que una implementacin POA puede utilizar como metodologa base cualquier paradigma de programacin, manteniendo intactos los beneficios de ese paradigma de programacin. Se elige POO como el sistema base para obtener los beneficios de una mejor implementacin de los conceptos comunes. Bajo esta implementacin los conceptos individuales pueden emplear tcnicas orientadas a objetos. Esto es anlogo a la forma en que actan los lenguajes procedurales como lenguaje base a muchos lenguajes orientados a objetos [18]. 5.2 Trabajos relacionados El tpico de separacin de conceptos ha sido un tema de investigacin fuerte en los ltimos aos, con distintos nombres en cada caso. En la Universidad de Northeastern ha recibido el nombre de Programacin Adaptativa por Karl Lieberherr[40]. En la Universidad de Twente, Holanda, recibe el nombre de Filtros de Composicin por Mehmet Aksit[41]. En IBM Research, Yorktown Heights(N.Y.), se la conoce como Programacin Subjetiva, y uno de sus proyectos es el sistema HyperJ[28] para
www.programemos.com Pgina 90/123

www.programemos.com

programacin en Java. Tambin se puede citar el trabajo de Mira Mezini[42], en la Universidad de Siegen, en Alemania, en el proyecto Optimizacin en la Modularidad y Reusabilidad del Software Orientado a Aspectos. Otra tema de investigacin relacionado es la Meta Programacin Lgica Orientada a Aspectos(Logic POA), creada por Johan Brichau y Kris De Volder. Esta aproximacin representa los programas como hechos lgicos y describe a los aspectos como programas meta-lgicos que entrecruzan la modularidad del nivel base. Esto permite definir lenguajes orientados a aspectos nuevos y ms especficos en trminos de lenguajes orientados a aspectos ya existentes. Actualmente estn investigando cmo un modelo de aspectos encapsulado como programas meta-lgicos puede ser usado para soportar combinaciones de lenguajes de aspectos. Existen otras reas de investigacin que si bien no estn fuertemente relacionadas con aspectos comparten problemas y objetivos. Tres ejemplos de ellas son: [19] Reflexin y protocolos de metaobjetos : Un sistema reflectivo proporciona un lenguaje base y uno o ms metalenguajes que proporcionan control sobre la semntica del lenguaje base y la implementacin. Los metalenguajes proporcionan vistas de la computacin que ningn componente del lenguaje base puede percibir. Los metalenguajes son de ms bajo nivel que los lenguajes de aspectos en los que los puntos de enlace son equivalentes a los ganchos de la programacin reflexiva. Estos sistemas se pueden utilizar como herramienta para la programacin orientada a aspectos. Transformacin de programas: El objetivo que persigue la transformacin de programas es similar al de la orientacin a aspectos. Busca el poder escribir programas correctos en un lenguaje de ms alto nivel, y luego, transformarlos de forma mecnica en otros que tengan un comportamiento idntico, pero cuya eficiencia sea mucho mejor. Con este estilo de programacin algunas propiedades de las que el programador quiere implementar se escriben en un programa inicial. Otras se aaden gracias a que el programa inicial pasa a travs de varios programas de transformacin. Esta separacin es similar a la que se produce entre los componentes y los aspectos. Programacin subjetiva: es muy similar a la programacin orientada a aspectos pero no representan exactamente el mismo concepto. La programacin subjetiva soporta la combinacin automtica de mtodos para un mensaje dado a partir de diferentes sujetos. Estos mtodos seran equivalentes a las componentes de la POA. La diferencia clave entre ambas disciplinas es que mientras que los aspectos de la POA tienden a ser propiedades que afectan al rendimiento o la semntica de los componentes, los sujetos de la programacin subjetiva son caractersticas adicionales que se agregan a otros sujetos. 5.3 POA: Ventajas y desventajas
5.3.1 Ventajas

R. Laddad en [18], enumera algunas de las principales ventajas del paradigma:


www.programemos.com Pgina 91/123

www.programemos.com

Ayuda a superar los problemas causados por el Cdigo Mezclado y Cdigo Diseminado (citados previamente en este trabajo). Implementacin modularizada: POA logra separar cada concepto con mnimo acoplamiento, resultando en implementaciones modularizadas an en la presencia de conceptos que se entrecruzan. Esto lleva a un cdigo ms limpio, menos duplicado, ms fcil de entender y de mantener. Mayor evolucionabilidad: La separacin de conceptos permite agregar nuevos aspectos, modificar y / o remover aspectos existentes fcilmente. Uno puede retrasar las decisiones de diseo sobre requerimientos actuales o que surjan en el futuro, ya que permite, luego, implementarlos separadamente, e incluirlos automticamente en el sistema; resolviendo el dilema del arquitecto: Cuntos recursos invertir en el diseo? Cundo es demasiado diseo? Mayor reusabilidad: Al ser implementados separadamente, tiene mayor probabilidades de ser reusados en otros sistemas con requerimientos similares. De nuestro anlisis del paradigma, podemos agregar otras tres ventajas: Dividir y conquistar: Al separar la funcionalidad bsica de los aspectos, se aplica con mayor intensidad el principio de dividir y conquistar. N-dimensiones: Ahora se tiene la posibilidad de implementar el sistema con las dimensiones que sean necesarias, no una nica dimensin sobrecargada. En pocas palabras, hace nfasis en el principio de mnimo acoplamiento y mxima cohesin.
5.3.2 Desventajas

En el anlisis de los LOA se han hallado tres falencias [1], las cules surgen del hecho de que la POA est en su infancia: Posibles choques entre el cdigo funcional (expresado en el lenguaje base) y el cdigo de aspectos (expresados en los lenguajes de aspectos). Usualmente estos choques nacen de la necesidad de violar el encapsulamiento para implementar los diferentes aspectos, sabiendo de antemano el riesgo potencial que se corre al utilizar estas prcticas. Posibles choques entre los aspectos. El ejemplo clsico es tener dos aspectos que trabajan perfectamente por separado pero al aplicarlos conjuntamente resultan en un comportamiento anormal. Posibles choques entre el cdigo de aspectos y los mecanismos del lenguaje. Uno de los ejemplos ms conocidos de este problema es la anomala de herencia [10]. Dentro del contexto de la POA, el trmino puede ser usado para indicar la dificultad de heredar el cdigo de un aspecto en la presencia de herencia. Nuestro anlisis nos permite observar tambin que los lenguajes orientados a aspectos actuales no cuentan con mecanismos lingsticos suficientemente poderosos para respetar por completo todos los principios de diseo, como por ejemplo, el encapsulamiento.

www.programemos.com Pgina 92/123

www.programemos.com

Referencias
Gianpaolo Cugola, Carlo Ghezzi, Mattia Monga, Language Support for Evolvable Software: An Initial Assessment of Aspect-Oriented Programming, in Proceedings of the International Workshop on the Principles of Software Evolution, IWPSE99, Julio 1999 . K. Mehner, A. Wagner, An Assessment Of Aspect Language Design, Position Paper in Young Researchers Workshop, GCSE 99, 1999. Ken Anderson, Thoughts On Aspect-Oriented Programming, Summarizing Cristina Lopes work, Northeastern University, 1996. Claire Tristram, Untangling Code, in the January/February 2001 issue of the Technology Review. Junichi Suzuki, Yoshikazu Yamamoto, Extending UML with Aspects: Aspect Support in the Design Phase, 3er Aspect-Oriented Programming(AOP) Workshop at ECOOP 99. Pascal Fradet, Mario Sdholt, An Aspect Language for robust programming, in Proceedings of the European Conference on Object-Oriented Programming (ECOOP) Workshops 1999. Gianpaolo Cugola, Carlo Ghezzi, Mattia Monga, Coding Different Design Paradigms for Distributed Applications with Aspect-Oriented Programming, in the Workshop su Sistemi Distribuiti: Algoritmi, Architetture e Linguaggi (WSDAAL). Septiembre 1999. Gregor Kickzales, John Lamping, Anurag Mendhekar, Chris Maeda, Cristina Videira Lopes, Jean-Marc Loingtier, John Irwin, Aspect-Oriented Programming, in Proceedings of the European Conference on Object-Oriented Programming (ECOOP), Finland. Springer-Verlag LNCS 1241. Junio 1997. Gregor Kickzales, Erik Hilsdale, Jim Hugunin, Mik Kersten, Jeffrey Palm, William G. Grisnold, Getting Started with AspectJ, in Communications of the ACM (CACM) , Vol 44, N 10, Octubre 2001. S. Matsuoka, A. Yonezawa, Analysis of inheritance anomaly in object-oriented concurrent programming languajes, in Research Directions in Concurrent Object-Oriented Programming (G. Agha, P.Wegner, and A. Yonezawa, eds.),pp. 107-150, Cambridge, MA: MIT Press, 1993. Parnas D.L., On the Criteria to be used in decomposing Systems into Modules, in Communications of the ACM,vol. 15(2),1972.

www.programemos.com Pgina 93/123

www.programemos.com

Parnas D.L., Designing Software for Extension and Contractions, in Proceedings 3er International Conference on Software Engineering,pp. 264277,1978. Pgina del grupo Demeter: http://www.ccs.neu.edu/research/demeter/ . John Lamping, The role of the base in aspect oriented programming , in Proceedings of the European Conference on Object-Oriented Programming (ECOOP) Workshops 1999. Timothy Highley, Michael Lack, Perry Myers, Aspect-Oriented Programming: A Critical Analysis of a new programming paradigm , University of Virginia, Department of Computer Science, Technical Report CS-99-29, Mayo 1999. MacLennan B, Principles of Programming Languages: Design, Evaluation and Implementation, Oxford: NY, 1987. Carlo Ghezzi, Mehdi Jazayeri, Programming language concepts, 3 Edicin, John Wiley & Sons, 1998. Ramnivas Laddad, I want my AOP, Part 1,2 and 3, from JavaWorld, EneroMarzo-Abril 2002. Antonia Ma Reina Quintero, Visin General de la Programamcin Orientada a Aspectos, Departamento de Lenguajes y Sistemas Informticos, Universidad de Sevilla, diciembre de 2000. L.Berger, Junction Point Aspect: A Solution to Simplify Implementation of Aspect Languages and Dynamic Management of Aspect Programs, in Proceedings of ECOOP 2000, Junio de 2000, Francia. Peter Kenens, Sam Michiels, Frank Matthijs, Bert Robben, Eddy Truyen, Bart Vanhaute, Wouter Joosen, Pierre Verbaeten, An AOP Case with Static and Dynamic Aspects, Departament of Computer Science, K.U. Leuven, Blgica. Gregor Kickzales, John Lamping, Cristina Lopes, Chris Maeda, Anurag Mendhekar, Gail Murphy, Open Implementation Design guidelines, in Proceedings of the 19th International Conference on Sofware Engineering, (Boston, MA), mayo de 1997. Cristina Lopes, D: A Language Framework for Distributed Programming, Ph.D. thesis, Northeastern University, Noviembre de 1997. Mattia Monga, Concern Specific Aspect-Oriented Programming with Malaj, Politecnico de Milano, Dip. Di Elettronica e Informazione, Miln, Italia. Gianpaolo Cugola, Carlo Ghezzi, Mattia Monga, Gian Pietro Picco, Malaj: A Proposal to Eliminate Clashes Between Aspect-Oriented and Object-Oriented

www.programemos.com Pgina 94/123

www.programemos.com

Programming, Politecnico de Milano, Dip. Di Elettronica e Informazione, Miln, Italia. Robert Hirschfeld, AspectS AOP with Squeak, in Proceedings of OOPSLA 2001 Workshop on Advanced Separation of Concerns in Object-Oriented System, Agosto de 2001. Yvonne Coady, Gregor Kickzales, Mike Feeley, Greg Smolyn, Using AspectC to improve the modularity of path-specific customization in operating system code, in Proceedings of Joint ESEC and FSE-9, 2001. Harold Ossher, Peri Tarr, Multi-Dimensional Separation of Concerns and the Hyperspace Approach, in Proceedings of the Symposium on Software Arquitectures and Component Technology: The state of the Art in Sofware Development. Kluwer, 2001. Andreas Gal, Wolfgan Schroder, Olaf Spinczyk, AspectC++: Language Proposal and Prototype Implementation, University of Magdeburg, Alemania, 2001. Kris de Volder, Theo D Hondt, Aspect-Oriented Logic Meta Programming, in Proceedings of Meta-Level Architectures and Reflection, Second International Conference, Reflection'99. LNCS 1616, pp. 250-272, Springer-Verlag,1999. Johan Brichau, Declarative Composable Aspects , in Proceedings of OOPSLA 2000 Workshop on Advanced Separation of Concerns, Septiembre de 2000. Ralf Lammel, Gunter Riedewald, Wolfgang Lohmann, Adaptation of functional object programs, Position Paper at the ECOOP 99 Workshop on AspectOriented Programming. Ralf Lammel, Declarative aspect-oriented programming, in Proceedings PEPM99, 1999 ACM SIGPLAN Workshop on Partial Evaluation and SemanticsBased Program Manipulation PEPM99, San Antonio (Texas), BRICS Notes Series NS-99-1, pginas 131-146, Enero de1999. B. Wulf, M. Shaw, Global Variables Considered Harmful, SIGPLAN Notices, vol.8, No. 2, February, 1972. El sitio de AspectJ: www.aspectj.org . Palo Alto Research Center. Johan Brichau, Wolfgang De Meuter, Kris de Volder, Jumping Aspect, Programming Technology Lab, Vrije Universiteit Brussel, Blgica, Abril de 2000. Pgina de Mark Benvenuto: http://www.cs.columbia.edu/~markb/ . Pgina de Squeak: http://squeak.org . Pgina de TyRuBa: http://tyruba.sourceforge.net .

www.programemos.com Pgina 95/123

www.programemos.com

Pgina de Karl Lieberherr: http://www.ccs.neu.edu/home/lieber/ . Pgina de Mehmet Aksit: http://trese.cs.utwente.nl/aksit/aksit_trese.htm . Pgina de Mira Mezini: http://www.informatik.uni-siegen.de/~mira/ . Wai-Ming Ho, Franois Pennaneach, Jean Marc Jezequel, Nol Plouzeau, Aspect-Oriented Design with the UML, in Proceedings of Multi-Dimensional Separation of Concerns Workshop at ICSE, junio de 2000. Siobhan Clarke, John Murphy. Developing a Tool to support Aspect-Oriented Programming principles to the Design phase, in Proceedings of ICSE '98 Workshop on Aspect-Oriented Programming. Jos Luis Herrero, Fernando Snchez, Fabiola Lucio, Miguel Toro, Introducing Separation of Aspects at Design Time, in Proceedings of AOP Workshop at ECOOP '00, Cannes, France, junio de 2000. R. Buhr, A possible design notation for aspect oriented programming, in Proceedings of the Aspect-Oriented Programming Workshop at ECOOP'98, julio de 1998. Pascal Fradet, Mario Sdholt, AOP: towards a generic framework using program transformation and analysis, in Proceedings of the Aspect-Oriented Programming Workshop at ECOOP'98, julio de 1998. Wolfgang De Meuter, Monads as a theoretical foundation for AOP, in Proceedings of the Aspect-Oriented Programming Workshop at ECOOP'97. James H. Andrews, Using process algebra as a foundation for programming by separation of concerns, Department of Computer Science, University of Western Ontario, Ontario, Canada. Bernardo Ezequiel Contreras y Fernando Asteasuain POA: Anlisis del Paradigma: http://www.angelfire.com/ri2/aspectos/

www.programemos.com Pgina 96/123

www.programemos.com

BORRADORES DE PUNTOS
3.9.1 Puntos de enlace

Para entender el concepto de punto de enlace consideremos el siguiente ejemplo, en el cual se define una clase para manejar nmeros complejos: Class NumComplejo{ private real parte_imaginaria, parte_real; NumComplejo(real x, real y){ this.parte_imaginaria=x; this.parte_real=y; } void ingresar_parte_imaginaria(real x){ this.parte_imaginaria=x; } void ingresar_parte_real(real y){ this.parte_real=y; } real devolver_parte_ imaginaria(){ return parte_imaginaria; } real devolver_parte_real(){ return parte_real; } void aumentar_parte_real(real x) { real a = devolver_parte_real(); a= a+x; ingresar_parte_real(a); } } Cdigo 1: Clase nmero complejo.

Entonces lo que establece el cdigo void ingresar_parte_ imaginaria(real x){ this.parte_imaginaria=x; } es que cuando el mtodo ingresar_parte_imaginaria es invocado con un real como argumento sobre un objeto de tipo NumComplejo entonces se ejecuta el cuerpo del mtodo. De igual forma cuando un objeto de tipo NumComplejo es instanciado a travs de un constructor con dos argumentos de clase real, entonces se ejecuta el cuerpo del constructor. El patrn que surge de esta descripcin es que cuando algo pasa entonces algo se ejecuta. El conjunto de las cosas que pasan representan los puntos de enlace.

www.programemos.com Pgina 97/123

www.programemos.com

Los puntos de enlace son entonces puntos bien definidos en la ejecucin de un programa y AspectJ define los siguientes conceptos: Llamadas a mtodos: Cuando un mtodo es invocado, no incluye llamadas a super. Ejemplo: cc.aumentar_parte_real_primera(5.5);. Cuando el mtodo aumentar_parte_real_primera es invocado sobre el objeto cc. Ejecucin de un mtodo: Cuando el cuerpo de un mtodo se ejecuta. Ejemplo: Cuando el cuerpo del mtodo aumentar_parte_real_primera es ejecutado. Llamada a un constructor: Cuando un objeto es creado y un constructor es invocado, sin incluir la llamada al constructor this o super. Ejemplo: NumComplejo nc1 = new NumComplejo(3.0,5.3);. El objeto es creado por new y luego el constructor NumComplejo es invocado. Ejecucin de un inicializador: Cuando los inicializadores no estticos de una clase se ejecutan. Ejecucin de un constructor: Cuando se ejecuta el cdigo de un constructor, luego de su llamada al constructor this o super. Ejemplo: Cuando el cdigo del constructor NumComplejo se ejecuta. Ejecucin de un inicializador esttico: Cuando se ejecuta el inicializador esttico para una clase. Pre-inicializacin de un objeto: Antes que el cdigo de inicializacin para una clase particular se ejecute. Comprende el tiempo entre el comienzo de la llamada al primer constructor y el comienzo del constructor de su clase padre. Luego, la ejecucin de estos puntos de enlace comprenden los puntos de enlace del cdigo encontrado en las llamadas a constructores this y super. Inicializacin de un objeto: Cuando el cdigo de inicializacin para una clase particular se ejecuta. Comprende el tiempo entre el retorno del constructor de su clase padre y el retorno de la llamada a su primer constructor. Incluye todos los inicializadores dinmicos y constructores usados para crear el objeto. Referencia a un atributo: Cuando se referencia a un atributo no final. Un atributo final es un atributo que no cambia su valor una vez inicializado. Asignacin a un atributo: Cuando se realiza la asignacin a un atributo. Ejemplo: numerocomplejo.parte_imaginaria=5.5;. Cuando al parte_imaginaria del objeto numerocomplejo se le asigna el valor real 5.5. Ejecucin de un manejador: Cuando el manejador de una excepcin se ejecuta. El modelo de punto de enlaces es un elemento crtico en el diseo de cualquier LOA ya que provee la interface entre el cdigo de aspectos y el cdigo de la funcionalidad bsica. En AspectJ este modelo puede considerarse como nodos en un grafo de llamadas a objetos en ejecucin. Estos nodos incluyen puntos en los cuales un objeto recibe una llamada a un mtodo o puntos en los cuales un atributo de un objeto es
www.programemos.com Pgina 98/123

atributo

www.programemos.com

referenciado. Los arcos representan el flujo de control entre los nodos. En este modelo el control pasa por cada punto de enlace dos veces, una cuando realiza el clculo y otra al regresar del mismo. Como ejemplo del modelo, consideremos la siguiente clase, y la figura 10: Class CoordenadaCompleja { NumComplejo NumComplejo1,NumComplejo2; real distancia; ... void aumentar_parte_real_primera(real x){ ... real s = this.distancia; NumComplejo1.aumentar_parte_real(x); ... } ... } Cdigo 2: Clase coordenada compleja.

NumComplejo nc1 = new NumComplejo(3.0,5.3); NumComplejo nc2 = new NumComplejo(6.2,1.3); CoordenadaCompleja cc = new CoordenadaCompleja(nc1,nc2); cc.aumentar_parte_real_primera(5.5); cc Mt2 M nc1 Mt3

Mt4
www.programemos.com Pgina 99/123

www.programemos.com

nc2

Figura 10: Modelo de puntos de enlace = Mtodos. = Clculo. Mt1 = aumentar_parte_real_primera, de la clase CoordenadaCompleja. Mt2 = ingresar_parte_real, de la clase NumComplejo. Mt3 = devolver_parte_real, de la clase NumComplejo. Mt4 = aumentar_parte_real, de la clase NumComplejo. La ejecucin de las tres primeras lneas de la figura 10 provoca la creacin de los objetos cc, nc1 y nc2. La ejecucin de la ltima lnea inicia una computacin que ir siguiendo los puntos de enlace: Un punto de enlace de llamada a un mtodo, correspondiente al mtodo aumentar_parte_real_primera invocado sobre el objeto cc. Un punto de enlace de recepcin de llamada a un mtodo, en el cual cc recibe la llamada aumentar_parte_real_primera. Un punto de enlace de ejecucin de un mtodo, en el cual el mtodo aumentar_parte_real_primera definido en la clase CoordenadaCompleja empieza su ejecucin. Un punto de enlace de acceso a un atributo, en el cual el atributo distancia de cc es referenciado. Un punto de enlace de llamada a un mtodo, en el cual el mtodo aumentar_parte_real es invocado sobre el objeto nc1. Un punto de enlace de recepcin de llamada a un mtodo, en el cual nc1 recibe la llamada aumentar_parte_real. Un punto de enlace de ejecucin de un mtodo, en el cual el mtodo aumentar_parte_real definido en la clase NumComplejo empieza su ejecucin. Un punto de enlace de llamada a un mtodo, en el cual el mtodo devolver_parte_real es invocado sobre el objeto nc1. Un punto de enlace de recepcin de llamada a un mtodo, en el cual nc1 recibe la llamada devolver_parte_real. Un punto de enlace de ejecucin de un mtodo, en el cual el mtodo devolver_parte_real definido en la clase NumComplejo empieza su ejecucin.
www.programemos.com Pgina 100/123

= Puntos de Enlace.

= Objetos.

www.programemos.com

El control retorna por los puntos de enlace 10 y 9. Un punto de enlace de llamada a un mtodo, en el cual el mtodo ingresar_parte_real es invocado sobre el objeto nc1. ... y as siguiendo, hasta que finalmente el control retorna por los puntos de enlace 3, 2 y 1.
3.9.2 Cortes

Un corte es un conjunto de puntos de enlace ms datos del contexto de ejecucin de dichos puntos. Los cortes principalmente son usados por los avisos y pueden ser compuestos con operadores booleanos para crear otros cortes. AspectJ provee varios designadores de cortes primitivos. El programador luego puede componerlos para definir designadores de cortes annimos o con nombres. Los cortes no son de alto orden, porque sus argumentos y resultados no pueden ser cortes ni existen designadores de cortes paramtricos. Un designador de corte captura en ejecucin varios puntos de enlace, por ejemplo el designador: call(void NumComplejo.ingresar_parte_real(real)) captura todas las llamadas al mtodo ingresar_parte_real de la clase NumComplejo con un argumento de clase real. Otro ejemplo sera: pointcut acceso(): get(NumComplejo.parte_real) || get(CoordenadaCompleja.distancia); este designador de corte captura todas las referencias al atributo parte_real de la clase NumComplejo o todas las referencias al atributo distancia de la clase CoordenadaCompleja. Como vemos los designadores de cortes pueden capturar puntos de enlaces de diferentes clases, esto es, entrecruzan las clases.
Cortes primitivos

AspectJ incluye una variedad de designadores de cortes primitivos que identifican puntos de enlace de diferentes formas. Los designadores de cortes primitivos son: Call : call(PatrndeMtodo), call(PatrndeConstructor). Captura todos los puntos de enlace de llamadas a mtodos o constructores cuyo encabezamiento coincide con el respectivo patrn. Ejemplo: call( * NumComplejo.* (..))
www.programemos.com Pgina 101/123

www.programemos.com

captura todos los puntos de enlace de llamadas a cualquier mtodo, que devuelve cualquier tipo y con cualquier nmero y tipo de argumentos, de la clase NumComplejo. Los patrones se refieren a expresiones como NumComplejo.* que permite identificar todos los mtodos de la clase NumComplejo. Execution: execution(PatrndeMtodo), execution(PatrndeConstructor). Captura todos los puntos de enlace de ejecucin de mtodos o constructores cuyo encabezamiento coincide con el respectivo patrn. Ejemplo: execution(NumComplejo.new(..)) captura la ejecucin de los constructores de la clase NumComplejo con cualquier nmero de argumentos. Get: get(PatrndeAtributo) Captura todos los puntos de enlace de referencia a los atributos que coinciden con el patrn correspondiente. Ejemplo: get(NumComplejo.parte_imaginaria) captura las referencias al atributo parte_imaginaria de la clase NumComplejo. Set: set(PatrndeAtributo) Captura todos los puntos de enlace de asignacin a los atributos que coinciden con el patrn correspondiente. Ejemplo: set(NumComplejo.parte_*) captura las asignaciones a los atributos de la clase NumComplejo que coinciden con el patrn parte_*, en este caso coinciden parte_imaginaria y parte_real. Initialization: initialization(PatrndeConstructor) Captura los puntos de enlace de las inicializaciones de los objetos cuyos constructores coinciden con el patrn . Staticinitialization: staticinitialization(PatrndeClase) Captura los puntos de enlace de ejecucin de un inicializador esttico de las clases que coinciden con el patrn. Handler: handler(PatrndeClase) Captura los manejadores de excepcin de las clases de excepciones que coinciden con el patrn. This: this(PatrndeClase), this(identificador) Captura todos los puntos de enlace donde el objeto actual (el objeto ligado a this) es una instancia de una clase que coincide con el PatrndeClase, o es instancia de una clase que coincide con la clase asociada al identificador. Target: target(PatrndeClase), target(identificador) Captura todos los puntos de enlace donde el objeto objetivo (el objeto sobre el cual se invoca un mtodo o una operacin de atributo) es una instancia de una clase que
www.programemos.com Pgina 102/123

www.programemos.com

coincide con el PatrndeClase, o es instancia de una clase que coincide con la clase asociada al identificador. Args: args(PatrndeClase, . . .),args(identificador, . . .) Captura todos los puntos de enlace donde los argumentos son instancias de una clase que coincide con el PatrndeClase o con la clase del identificador. Si es un PatrndeClase entonces el argumento en esa posicin debe ser instancia de una clase que coincida con el PatrndeClase. Si es un identificador entonces el argumento en esa posicin debe ser instancia de una clase que coincida con la clase asociada al identificador (o cualquier clase si el identificador est asociado a Object. Este caso especial se ver nuevamente en la seccin Exposicin de contexto). Ejemplo: args(*,int) captura todos los puntos de enlace con dos argumentos, el primero puede ser cualquiera y el segundo debe ser un entero. Within: within(PatrndeClase) Captura todos los puntos de enlace donde el cdigo que se est ejecutando est definido en una clase que coincide con el patrn. Incluye la inicializacin de la clase, del objeto, puntos de enlaces de ejecucin de mtodos y constructores, y puntos de enlaces asociados con las sentencias y expresiones de la clase. Ejemplo: within(NumComplejo) captura todos los puntos de enlace donde el cdigo que se est ejecutando est definido dentro de la clase NumComplejo. Withincode: withincode(PatrndeMtodo),withincode(PatrndeConstructor) Captura todos los puntos de enlace donde el cdigo que se est ejecutando est definido en un mtodo o constructor que coincide con el patrn correspondiente. Incluye todos los puntos de enlace de ejecucin de mtodos y constructores, y puntos de enlaces asociados con las sentencias y expresiones del mtodo o constructor. Ejemplo: withincode(real devolver_parte_real()) captura todos los puntos de enlace donde el cdigo que se est ejecutando est definido en el mtodo devolver_parte_real. Estos dos ltimos cortes primitivos, within y withincode, tratan con la estructura lxica del programa. Cflow: cflow(Corte) Captura todos los puntos de enlace en el flujo de control de los puntos de enlace capturados por el corte pasado como parmetro. Ejemplo: cflow(withincode(real devolver_parte_real())) captura todos los puntos de enlace que ocurren entre el comienzo y la finalizacin de los puntos de enlace especificados por withincode(real devolver_parte_real()). Cflowbelow: cflowbelow(Corte)

www.programemos.com Pgina 103/123

www.programemos.com

Captura todos los puntos de enlace en el flujo de control debajo de los puntos de enlace capturados por el corte pasado como parmetro, sin incluir el punto de enlace inicial del flujo de control. Ejemplo: cflowbelow(withincode(real devolver_parte_real())) captura todos los puntos de enlace que ocurren entre el comienzo y la finalizacin de los puntos de enlace especificados por withincode(real devolver_parte_real()), pero no lo incluye a ste. If: if(Expresinbooleana) Captura todos los puntos de enlace cuando la expresin booleana se satisface.
Cortes definidos por el programador

El programador puede definir nuevos cortes asocindoles un nombre con la declaracin pointcut. pointcut nombre(<Parametros_formales>): <Corte>; donde <Parametros_formales> expone el contexto del corte, y < Corte> puede ser un corte primitivo o definido por el programador. Ejemplo: /* Corte1 */ pointcut aumentar(): call(void aumentar*()) ; /* Corte2 */ pointcut aumentarsolocomplejo(): aumentar() && target(NumComplejo); Corte1 captura todas las llamadas a un mtodo que comience con la palabra aumentar. Corte2 utiliza Corte1 para capturar aquellas llamadas a mtodos que empiecen con aumentar pero que sean invocados slo sobre un objeto de clase NumComplejo. Un corte nombrado puede ser definido tanto en una clase como en un aspecto y es tratado como un miembro de esa clase o aspecto. Como miembro puede tener modificadores de acceso privado o pblico (private o public). No se permite la sobrecarga de cortes definidos por el programador. Por lo tanto ser un error de compilacin cuando dos cortes en una misma clase o aspecto tengan asociado el mismo nombre. Esta es una de las diferencias con la declaracin de mtodos. El alcance de un corte definido por el programador es la declaracin de la clase o aspecto que lo contiene. Es diferente al alcance de otros miembros que slo se limitan al cuerpo de la clase o aspecto. Los cortes pueden declararse como abstractos, y son definidos sin especificar su cuerpo. Estos cortes slo pueden declararse dentro de un aspecto declarado abstracto.
Composicin de cortes

www.programemos.com Pgina 104/123

www.programemos.com

Tanto los cortes definidos por el programador como los primitivos pueden componerse entre s a travs de la utilizacin de operadores algebraicos para crear nuevos cortes. Los operadores algebraicos soportados por AspectJ son: && ( y ), || (o), !(no) y los parntesis. Lo anterior puede modelarse a travs de una BNF : <Corte>::= <Corte_Primitivo>| <Corte_Definido_por_el_programador> | <Corte> && <Corte> | <Corte> || <Corte> | !<Corte> | (<Corte>) BNF 1: Definicin de cortes donde la semntica asociada a los operadores es la siguiente: <Corte>1 && <Corte>2 : captura todos los puntos de enlace de Corte1 y todos los puntos de enlace de Corte2. <Corte>1|| <Corte>2 : captura todos los puntos de enlace de Corte1 o todos los puntos de enlace de Corte2. !<Corte>: captura todos los puntos de enlace que no captura Corte. (<Corte>): captura todos los puntos de enlace que captura Corte. Esto es, el resultado de componer uno o ms cortes tambin es un corte. La composicin de los cortes resulta uno de los mecanismos ms importantes para permitir la expresividad en el manejo de aspectos de AspectJ. La composicin es sencilla y simple, a travs de operadores bien conocidos. Dara la impresin que esta simplicidad tendra como efecto secundario una prdida importante en el poder de expresividad; pero esto no es as ya que se pueden obtener expresiones tan complejas como se requiera. La composicin es entonces un mecanismo muy poderoso, y an as mantiene su simplicidad. Como ejemplo, consideremos la siguiente implementacin de una pila para la cual cada vez que un elemento es agregado, se desea mostrar la pila resultante. Para esto, se define un corte que captura todas las llamadas al mtodo apilar: pointcut al_apilar() : call(void Pila.Apilar(Object)); Si bien con este corte se capturan los puntos de enlace deseados, caemos en un problema de eficiencia porque en el mtodo Apilar_Multiple, por cada elemento se invoca al mtodo Apilar. Idealmente, en el caso de este mtodo, la pila se debera mostrar una vez que se apilaron todos los elementos, y no cada vez que se apila un elemento. Class Pila {
www.programemos.com Pgina 105/123

www.programemos.com

private Object [] arreglo ; private int ultimo; private int capacidadMaxima=100; public Pila() { arreglo = new Object[capacidadMaxima]; ultimo=0; } public void Apilar(Object elem) { arreglo[ultimo] = elem; ultimo++; } public Object Desapilar(){ Object elem = arreglo[ultimo-1]; ultimo--; return elem; } public void Apilar_Multiple(Object[] arregloElem){ for (int i=0,i<=arregloElem.length,i++){ this.apilar(arregloElem[i] ); } } public int Dar_Capacidad_Maxima(){ return capacidadMaxima;} public int Cantidad_Elementos() {return ultimo;} public boolean Pila_Vacia(){return (ultimo==0);} public boolean Pila_ Llena(){return (ultimo==capacidadMaxima);} } Cdigo 3: Definicin clase pila. Para discriminar estos dos casos y solucionar el problema, utilizamos la composicin de cortes: pointcut al_apilar_deauno(): al_apilar() && !withincode(void Pila.Apilar_Multiple(..)); pointcut al_apilar_multiple(): call(void Pila.Apilar_Multiple(..)); pointcut al_apilar_eficiente(): al_apilar_deauno() && al_apilar_multiple(); El corte al_apilar_deauno captura todas las invocaciones al mtodo Apilar que no estn dentro del cdigo de Apilar_Multiple. El corte al_apilar_multiple captura todas las invocaciones al mtodo Apilar_Multiple. Y el ltimo corte, al_apilar_eficiente, captura los puntos de enlace del primer y segundo corte, solucionado as el problema de eficiencia. Como vemos la composicin de cortes de AspectJ nos permite modelar una situacin dinmica, en el cual el punto de enlace depende del contexto dinmico de ejecucin [36]: en nuestro ejemplo, dentro de todas las invocaciones al mtodo Apilar necesitamos descartar las que se realicen desde el cdigo de Apilar_Multiple. Para ello
www.programemos.com Pgina 106/123

www.programemos.com

debemos analizar dinmicamente cada invocacin al mtodo Apilar y descartar aquellas que estn en el contexto de Apilar_Multiple. Otro ejemplo ms sencillo de composicin sera obtener los momentos donde otros objetos requieran el valor de los atributos de la pila, en particular capacidadMaxima y ultimo. Esto se logra con el siguiente corte: pointcut atributos_leidos(): (call (int Pila.Dar_Capacidad_Maxima(..)) || call (int Pila. Cantidad_Elementos(..)) ) && !this(Pila) ; El corte atributos_leidos captura todas las llamadas a los mtodos Dar_Capacidad_Maxima y Cantidad_Elementos tal que el llamador no es un objeto de la clase Pila.
Exposicin de contexto

Los cortes pueden exponer el contexto de ejecucin en sus puntos de enlace a travs de una interface. Dicha interface consiste de parmetros formales en la declaracin de los cortes definidos por el programador, anlogo a los parmetros formales en un mtodo. Una lista de parmetros vaca, como en el ejemplo anterior, significa que cuando los eventos ocurren ningn contexto est disponible, en cambio pointcut atributos_leidos(Pila p): (call (int Pila.Dar_Capacidad_Maxima(..)) || call (int Pila. Cantidad_Elementos(..)) ) && !this(Pila) && target(p); sera obtener los momentos donde otros objetos requieran el valor de los atributos de la pila y disponer del objeto de clase Pila receptor de los mensajes a travs del parmetro p, que es instanciado por el corte primitivo target. El contexto disponible en este caso es p. En la parte derecha de la declaracin de un corte o de un aviso se permite un identificador en lugar de especificar una clase o PatrndeClase. Existen tres cortes primitivos donde esto se permite: this, target y args. Usar un identificador en vez de un PatrndeClase es como si la clase seleccionada fuera de la clase del parmetro formal, por lo tanto en el ejemplo anterior target(p) captura todos los objetos receptores de clase Pila. Otro ejemplo de exposicin de contexto sera: pointcut puntosiguales(Punto p): target(Punto) && args(p) && call(boolean igual(Object )); donde suponemos definida la clase Punto con un mtodo pblico igual que recibe como parmetro otro objeto de clase Punto y retorna un valor booleano estableciendo si las coordenadas de ambos objetos son iguales o no.

www.programemos.com Pgina 107/123

www.programemos.com

El corte tiene un parmetro de clase Punto, entonces cuando los eventos descriptos en la parte derecha ocurren un objeto p de clase Punto est disponible. Pero en este caso si miramos con atencin la parte derecha el objeto disponible no es el objeto receptor del mtodo sino el objeto pasado como parmetro en dicho mtodo. Si queremos acceder a ambos objetos el corte debe ser definido como sigue: pointcut puntosiguales(Punto p1,Punto p2): target(p1) && args(p2) && call(boolean igual(Object )); donde p1 expone el objeto de clase Punto receptor del mtodo igual y p2 expone el objeto de clase Punto que es pasado como parmetro al mtodo igual . La definicin de los parmetros en un corte es flexible. Sin embargo la regla ms importante a tener en cuenta es que cuando cada uno de los eventos definidos ocurre todos los parmetros del corte deben ligarse a algn valor. Por consiguiente este corte dara un error de compilacin : pointcut enDosPilas(Pila p1, Pila p2) : (target(p1) && call(void Pila.Apilar(..))) || (target(p2) && call(Object Pila.Desapilar(..))); El corte anterior captura las llamadas al mtodo Apilar en un objeto p1 de clase Pila o las llamadas al mtodo Desapilar en un objeto p2 de clase Pila. El problema es que la definicin de los parmetros intenta acceder a dos objetos de clase Pila. Pero cuando el mtodo Apilar es llamado sobre un objeto no existe otro objeto de clase de Pila accesible, por lo que el parmetro p2 quedara sin un valor ligado y de ah el error de compilacin. La otra situacin sera cuando el mtodo Desapilar es llamado sobre un objeto y el parmetro p1 quedara sin un valor asociado resultando en el mismo error. Un caso especial de exposicin de contexto se da al utilizar la clase Object: pointcut llamadaspublicas( ): call(public *.*(..)) && args(Object); este corte captura todos los mtodos pblicos unarios que toman como nico argumento subclases de Object pero no los tipos primitivos como int. Pero : pointcut llamadaspublicas(Object o): call(public *.*(..)) && args(o); captura todos los mtodos unarios con cualquier clase de argumento, si el argumento fuera de tipo int el valor ligado a o sera de la clase java.lang.Integer.
Patrones

En esta seccin se describen los patrones que permite especificar AspectJ. Un PatrndeMtodo es una descripcin abstracta que permite agrupar uno o ms mtodos segn su encabezamiento. Un patrn para los mtodos sigue el siguiente esquema:
www.programemos.com Pgina 108/123

www.programemos.com

<PatrndeMtodo>::= [<ModificadoresdeMetodos>] <PatrndeClase>[<PatrndeClase>.] <PatrndeIdentificador>(<PatrondeClase>,...)[throws<PatrndeExcepcin> ] BNF 2: Patrones de mtodos El esquema incluye los modificadores de mtodos como static, private o public, luego las clases de los objetos retornados, las clases a las cuales pertenece el mtodo, el nombre del mtodo, que puede ser un patrn, los argumentos, que tambin pueden ser patrones, y la clusula throws que corresponda. La lista de parmetros formales puede utilizar el wildcard .. para indicar cero o ms argumentos. Luego execution(void m(..,int)) captura los mtodos m cuyo ltimo parmetro es de tipo entero, incluyendo el caso de que tenga un slo parmetro entero. Mientras que execution(void m(..)) captura todos los mtodos m con cualquier cantidad de argumentos. Los nombres de mtodos pueden contener el wildcard * que indica cualquier nmero de caracteres en el nombre del mtodo. Luego call( boolean *()) captura todos los mtodos que retornan un valor booleano sin tener en cuenta el nombre de los mtodos. En cambio call(boolean dar*()) captura todos los mtodos que retornan un valor booleano cuyo nombre empiece con el prefijo dar. Tambin se puede utilizar este wildcard en el nombre de la clase que contiene al mtodo. call(*.Apilar(..)) captura todas las llamadas al mtodo Apilar definido en cualquier clase. Mientras que call(Pila.Apilar(..)) captura todas las llamadas al mtodo Apilar definido en nicamente en la clase Pila. De no estar presente un nombre de clase se asume el wildcard * indicando cualquiera de las clases definidas.

www.programemos.com Pgina 109/123

www.programemos.com

Un PatrndeClase es un mecanismo para agrupar un conjunto de clases y usarlo en lugares donde de otra forma se usara una sola clase. Las reglas para usar los patrones de clase son simples. Todos los nombres de clases son patrones de clase. Existe un nombre especial * que tambin es un patrn. El * captura todas las clases y tambin los tipos primitivos. Luego call(void Apilar(*)) captura todas las llamadas a los mtodos Apilar que tienen un nico argumento de cualquier clase. Los patrones de clase pueden tambin utilizar los wildcard * y ... El wildcard * indica cero o ms caracteres a excepcin del punto(.). Luego puede ser usado cuando las clases respetan una convencin para formar sus nombres. call(java.awt.*) captura todas las clases que comiencen con java.awt. y no tengan ms puntos. Esto es captura las clases en el paquete java.awt pero no clases interiores como java.awt.datatransfer o java.awt.peer. El wildcard .. indica cualquier secuencia de caracteres que comienza y termina con punto (.) , por lo tanto puede ser utilizado para agrupar todas las clases en cualquier subpaquete o todas las clases internas. Luego target(java.awt..*) captura todos los puntos de enlaces donde el objetivo es de una clase que comienza con java.awt.. Incluye clases definidas en java.awt tanto como clases definidas en java.awt.datatransfer o java.awt.peer, entre otras. A travs del wildcard + es posible agrupar todas las subclases de una clase o conjunto de clases. Este wildcard sigue inmediatamente al nombre de una clase. Entonces mientras que call (Pila.new()) captura todas las llamadas a constructores donde una instancia exclusivamente de la clase Pila se crea, call(Pila+.new()) captura todas las llamadas a constructores donde una instancia de cualquier subclase de la clase Pila, incluyendo a ella misma, es creada.

www.programemos.com Pgina 110/123

www.programemos.com

Los patrones de clase pueden componerse utilizando los operadores lgicos && (y), || (o), !(no) y los parntesis. Formalmente, la sintaxis de un PatrndeClase es especificada por la siguiente BNF. <PatrndeClase>::= <PatrndeIdentificador> [+] [ [] .. * ] | !<PatrndeClase> | <PatrndeClase> && <PatrndeClase> | <PatrndeClase> || <PatrndeClase> (<PatrndeClase>) BNF 3: Patrones de clase.
3.9.3 Avisos

Los avisos definen el cdigo adicional que se ejecuta en los puntos de enlace capturados por los cortes. Los avisos definen el comportamiento que entrecruza toda la funcionalidad, estn definidos en funcin de los cortes . La forma en que el cdigo del aviso es ejecutado depende del tipo del aviso. AspectJ soporta tres tipos de avisos. El tipo de un aviso determina cmo ste interacta con el punto de enlace sobre el cual est definido. AspectJ divide a los avisos en: Aviso Antes(Before): aquellos que se ejecutan antes del punto de enlace. Aviso Despus (After): aquellos que se ejecutan despus del punto de enlace. Aviso Durante (Around): aquellos que se ejecutan en lugar del punto de enlace. El aviso antes no agrega mayores dificultades. Por ejemplo, consideremos ahora agregar los controles al mtodo Apilar de la clase Pila definida anteriormente para que no efecte la operacin Apilar si es el caso de qu la pila est llena. pointcut al_apilar(Pila p) : call(void Pila.Apilar(..)) && target (p);

before(Pila p):al_apilar(p){ if(p.Pila_Llena()){ throw new ExcepcionPilaLlena(); } } De igual forma podemos controlar tambin que la operacin Desapilar no se realice cuando la pila est vaca. pointcut al_desapilar(Pila p) : call(Object Pila.Desapilar(..)) && target(p);
www.programemos.com Pgina 111/123

www.programemos.com

before(Pila p):al_desapilar(p){ if(p.Pila_Vacia()){ throw new ExcepcionPilaVacia(); } } El aviso despus se puede subdividir segn como sea el retorno del mtodo: normal, sealando una excepcin o sin importar el retorno. Como ejemplo consideremos nuevamente el problema de mostrar la pila cada vez que se agrega un elemento de manera eficiente. pointcut al_apilar_deauno(Pila p): al_apilar(p) && !withincode(void Pila.Apilar_Multiple(..)); pointcut al_apilar_multiple(Pila p): call(void Pila.Apilar_Multiple(..)) && target(p); pointcut al_apilar_eficiente(Pila p): al_apilar_deauno(p) && al_apilar_multiple(p); Completemos el ejemplo agregando el comportamiento adicional para mostrar la pila. after (Pila p):al_apilar_eficiente(p){ dibujaEstructura dibujante =new dibujaEstructura(); dibujante.dibujarPila(p); } Una vez que se efecte una modificacin en la pila, en este caso agregar un elemento, se insertar el cdigo necesario para dibujar la pila. Suponemos definida una clase dibujaEstructura la cual muestra en pantalla diversas estructuras como pilas, listas, tablas hash, etc. En este aviso no importa la forma en que retornan los mtodos Apilar y Apilar_Multiple. After () throwing (Exception e):call( public *.*(..)) { contadorDeExcepciones++; System.out.println(e); } Este aviso se ejecuta cada vez que se genera una excepcin en un mtodo pblico definido en cualquier clase, aumenta el contador de excepciones y muestra en pantalla la excepcin. Este aviso tiene en cuenta la forma de retorno de los mtodos, cuando retornan sealando una excepcin, y seala nuevamente la excepcin una vez que se ejecuta su cdigo. After () returning (int cantidaddeelementos): call(int Pila.Cantidad_Elementos(..)){ System.out.println(Retornando un valor entero+cantidaddeelementos); }

www.programemos.com Pgina 112/123

www.programemos.com

Este aviso se ejecuta luego de cada punto de enlace capturado por el corte pero slo en el caso de que su retorno sea normal. El valor retornado puede accederse a travs del identificador cantidaddeelementos. Una vez que se ejecut el aviso se retorna el valor. El aviso durante se ejecuta en lugar del punto de enlace asociado al mismo y no antes o despus de ste. El aviso puede retornar un valor, como si fuera un mtodo y por lo tanto debe declarar un tipo de retorno. El tipo de retorno puede ser void, indicando el caso en que en el aviso no se desee devolver valor alguno; en esta situacin el aviso retorna el valor que devuelve el punto de enlace. En el cuerpo del aviso se puede ejecutar la computacin original del punto de enlace utilizando la palabra reserva proceed(<Lista_Argumentos>), que toma como argumentos el contexto expuesto por el aviso y retorna el valor declarado en el aviso. int around(int i) : call(int Numero.suma(int)) && args(i) { int nuevoRetorno = proceed(i+1); return nuevoRetorno*3; } Este aviso captura todas las llamadas al mtodo suma, y en vez de ejecutar directamente el cuerpo del mtodo, empieza a computar el cdigo del aviso. Este cdigo reformula la llamada, cambiando el argumento de entrada i por i+1; invoca al mtodo suma a travs de proceed y finalmente el aviso retorna la respuesta multiplicada por tres. Si el valor de retorno del aviso es de clase Object, entonces el resultado del proceed es convertido a una representacin Object, an cuando ese valor sea un tipo primitivo. Sin embargo, cuando un aviso retorna un valor de clase Object, ese valor es convertido nuevamente a su representacin original. Luego, el siguiente aviso es equivalente al anterior: Object around(int i) : call(int Numero.suma(int)) && args(i) { Integer nuevoRetorno = proceed(i+1); return new Integer(nuevoRetorno*3); } En todos los tipos de avisos todos los parmetros se comportan exactamente como los parmetros de los mtodos. La semntica del pasaje de parmetros es pasaje de parmetros por valor. La nica manera de cambiar los valores de los parmetros o los valores de retorno de los puntos de enlace es utilizando el aviso durante. La declaracin de avisos puede describirse formalmente a partir de la siguiente BNF. <Aviso>::=<Tipo_aviso> : <Corte> {<Cuerpo>} <Tipo_aviso>::= <Aviso_antes> | <Aviso_despues> | <Aviso_durante> <Aviso_antes>::= before (<Parametros_formales>) <Aviso_despues> ::= after (<Parametros_formales>) <Forma_terminacion>
www.programemos.com Pgina 113/123

www.programemos.com

<Forma_terminacion>::= returning [(<Parametro_formal>) ] | throwing [(<Parametro_formal>) ] | <Aviso_durante>::= <Nombre_Clase> around (<Parametros_formales>) [ throws <Lista_Clases>] BNF 4: Definicin de avisos
Modelo de comportamiento

Mltiples avisos se pueden aplicar a un mismo punto de enlace. Para determinar el orden de aplicacin de los avisos se define una relacin de precedencia entre ellos. Las reglas de precedencia se describirn en la seccin 3.9.5 Precedencia de aspectos. Una vez que se arriba a un punto de enlace, todos los avisos del sistema son examinados para ver si alguno se aplica al punto de enlace. Aquellos que s, son agrupados, ordenados segn las reglas de precedencia, y ejecutados como sigue: Primero, cualquier aviso durante es ejecutado, los de mayor precedencia primero. Dentro del cdigo del aviso durante, la llamada a proceed() invoca al prximo aviso durante que le sigue en precedencia. Cuando ya no quedan ms avisos durante se pasa al punto 2). Se ejecutan todos los avisos antes segn su orden de precedencia (de mayor a menor). Se ejecuta la computacin del punto de enlace. La ejecucin de los avisos despus normal y despus con excepcin depende de cmo result la ejecucin en el punto 3) y de la terminacin de avisos despus normal y despus con excepcin ejecutados anteriormente. Si la terminacin es normal todos los avisos despus normal se ejecutan, los de menor precedencia primero. Si ocurre una excepcin todos los avisos despus con excepcin que coinciden con la excepcin se ejecutan, los de menor precedencia primero. (esto significa que los avisos despus con excepcin pueden manejar excepciones sealadas por avisos despus normal y despus con excepcin de menor precedencia. Se ejecutan todos los avisos despus, los de menor precedencia primero. Una vez que se ejecutan todos los avisos despus el valor de retorno del punto 3) (si es que hay alguno) es devuelto a la llamada proceed correspondiente del punto 1) y ese aviso durante contina su ejecucin. Cuando el aviso durante finaliza, el control pasa al prximo aviso durante con mayor precedencia. Cuando termina el ltimo aviso durante, el control retorna al punto de enlace.
Acceso reflexivo

AspectJ provee un variable especial, thisJointPoint, que contiene informacin reflexiva sobre el punto de enlace actual para ser utilizada por un aviso. Esta variable slo puede ser usada en el contexto de un aviso y est ligada a un objeto de clase JoinPoint que encapsula la informacin necesaria. La razn de su existencia es que algunos
www.programemos.com Pgina 114/123

www.programemos.com

cortes pueden agrupar un gran nmero de puntos de enlaces y es deseable acceder a la informacin de cada uno. before(Punto p): target(p) && call(*.*(..)){ System.out.println(accediendo+ thisJointPoint +en+p); } El ejemplo anterior muestra una manera bruta de efectuar trazas sobre todas las llamadas a mtodos de la clase Punto. La variable thisJointPoint puede usarse para acceder tanto a informacin esttica como dinmica sobre los puntos de enlace. Para aquellos casos en los que slo se desea la informacin esttica, AspectJ provee otra variable especial thisJoinPointStaticPart, de la clase JoinPoint.StaticPart, la cual est ligada a un objeto que contiene nicamente la informacin esttica. Dicho objeto es el mismo objeto que se obtendra con la siguiente expresin: thisJointPoint.getStaticPart()
3.9.4 Introducciones y declaraciones

Las declaraciones de avisos cambian el comportamiento de sus clases asociadas pero no modifican su estructura esttica. Para aquellos conceptos que operan sobre la estructura esttica de la jerarqua de clases, AspectJ provee formas de introduccin. Cada forma de introduccin ser miembro del aspecto que lo define, pero introduce un nuevo miembro en otra clase. En el siguiente ejemplo se introduce el atributo booleano atencion en la clase Biblioteca y lo inicializa con el valor true. Como est declarado private solamente puede ser accedido dentro del aspecto que incluye la declaracin. Si fuera declarado como public podra ser accedido por cualquier cdigo. Por omisin se asume como declarado package-protected y en este caso puede ser accedido por cualquier cdigo dentro del paquete. private boolean Biblioteca.atencion=true; Tambin se pueden introducir mtodos, incluyendo constructores, en una o ms clases utilizando un patrn de clase. public Pila.new(Object o){ arreglo = new Object[capacidadMaxima]; ultimo=0; this.Apilar (o) ; } El ejemplo anterior introduce un nuevo constructor en la clase Pila. No se puede introducir un constructor en una interface, y si el patrn de clase incluye una interface se producir un error.
www.programemos.com Pgina 115/123

www.programemos.com

Las formas de introduccin permiten tambin declarar que una o ms clases objetivo implementarn una interface o heredarn de otra clase desde ese momento en adelante. /* implementa una interface */ declare parents: Pila implements PilaAbstracta; /* hereda de un clase */ declare parents: PilaOrdenada extends Pila; Como efecto de estas declaraciones PilaOrdenada hereda de la clase Pila y Pila implementa la interface PilaAbstracta. Una misma declaracin puede introducir varios elementos en ms de una clase. public unaFecha (Perro||Gato).fechaUltimaVacuna(){ return fechaVacuna; } Introduce dos mtodos, uno en la clase Perro y otro en clase Gato; ambos mtodos tienen el mismo nombre, no tienen parmetros, retornan un objeto de clase unaFecha y tienen el mismo cuerpo. En el caso que las clases Perro o Gato no tengan definido un atributo fechaVacuna resultar en un error. Un aspecto puede introducir atributos y mtodos tanto en interfaces como en clases. Formalmente la declaracin de formas de introduccin se define con la siguiente BNF. <Introducciones>::=<IntroduccionesdeAtributos> | <IntroduccionesdeMetodos> | <IntroduccionesdeMetodosAbstractos>| <IntroduccionesdeConstructores> <IntroduccionesdeAtributos>::= [<Modificadores>] <Nombre_Clase> <PatrondeClase>.<Identificador> [= <expresin>] ; <IntroduccionesdeMetodos>::= [<Modificadores>] <Nombre_Clase> <PatrondeClase>.<Identificador>(<Parametros_formales>) [ throws <Lista_Clases>] {<Cuerpo>} <IntroduccionesdeMetodosAbstractos>::= abstract [<Modificadores>] <Nombre_Clase> <PatrondeClase>.<Identificador>(<Parametros_formales>) [ throws <Lista_Clases>] ; <IntroduccionesdeConstructores>::= [<Modificadores>] <PatrondeClase>.new(<Parametros_formales>)
www.programemos.com Pgina 116/123

www.programemos.com

[ throws <Lista_Clases>] {<Cuerpo>} BNF 5: Definicin de formas de introduccin La semntica de las formas de introduccin es la siguiente: Introduccin de atributos: el efecto de este tipo de introduccin es que todas las clases que coincidan con el patrn de clase soportarn el nuevo atributo especificado en la introduccin. Las interfaces que coincidan con el patrn de clase tambin soportarn el nuevo atributo. Introduccin de mtodos: el efecto de este tipo de introduccin es que todas las clases que coincidan con el patrn de clase soportarn el nuevo mtodo especificado en la introduccin. Las interfaces tambin soportarn el nuevo mtodo, an si el mtodo no es pblico o abstracto. Introduccin de mtodos abstractos: tiene el mismo efecto que la introduccin de un mtodo. Introduccin de constructores: el efecto de este tipo de introduccin es que todas las clases que coincidan con el patrn de clase soportarn el nuevo constructor especificado en la introduccin. Como hemos mencionado anteriormente no se pueden introducir constructores en una interface, luego es un error si el patrn de clase incluye una interface. La ocurrencia del identificador this en el cuerpo de la introduccin de un constructor o mtodo, o en el inicializador de una introduccin de atributo, hace referencia a la clase objetivo y no al aspecto.
3.9.5 Aspectos

Los aspectos son declarados en forma similar a la declaracin de clases. El aspecto es la unidad que encapsula puntos de enlace, cortes, avisos , introducciones y declaraciones, adems de poder definir sus propios mtodos y atributos. La diferencia con una clase es que un aspecto puede entrecruzar otras clases o aspectos, y que no son directamente instanciados con una expresin new, o procesos de clonado o serializacin. Los aspectos pueden incluir la definicin de un constructor pero dicha definicin no debe contener argumentos y no debe sealar excepciones chequeadas. Un aspecto puede ser definido en un paquete, o como un aspecto interno, esto es, puede ser miembro de una clase, una interface o un aspecto. Como primer ejemplo de la definicin de aspecto podemos implementar una traza sobre la clase Pila a travs de un aspecto TrazadoPila. Por cada llamada a los mtodos de la clase Pila se imprime el nombre del mtodo. aspect TrazadoPila{ pointcut LlamadasaPila():call(* Pila.*(..)); before():LlamadasaPila(){
www.programemos.com Pgina 117/123

www.programemos.com

System.out.println(Entrando al mtodo: + thisJointPoint); } after():LlamadasaPila(){ System.out.println(Retornando del mtodo: + thisJointPoint); } } Cdigo 4: Aspecto de traza para la clase pila. De no utilizar AspectJ , el cdigo de TrazadoPila estara diseminado por toda la clase Pila al comienzo y al final de cada uno de sus mtodos. Si se quiere modificar el mensaje que se muestra o los mtodos involucrados en la traza, implicara revisar todo el cdigo de la clase y realizar los cambios necesarios. Al tenerlo encapsulado como un aspecto dichas modificaciones son triviales y no corremos el riesgo de afectar la funcionalidad bsica. Reconsideremos el problema de agregar controles en los mtodos Apilar y Desapilar de la clase Pila. Sin AspectJ dicho cdigo queda diseminado en ambos mtodos con los problemas ya mencionados. En cambio si tomamos al control como un aspecto ControlPila quedara encapsulado en una nica unidad.

aspect Control Pila{ pointcut al_apilar(Pila p) : call(void Pila.Apilar(..)) && target (p); pointcut al_desapilar(Pila p) : call(Object Pila.Desapilar(..)) && target(p); before(Pila p):al_apilar(p){ if(p.Pila_Llena()){ throw new ExcepcionPilaLlena(); } } before(Pila p):al_desapilar(p){ if(p.Pila_Vacia()){ throw new ExcepcionPilaVacia(); } } } Cdigo 5: Aspecto de control para la clase pila. Estos dos aspectos trabajan independientemente sobre la clase Pila abstrayendo dos conceptos diferentes. Est claramente separada la funcionalidad bsica, en este caso el cdigo de la clase Pila , de los aspectos de control y traza, y los aspectos entre s. Sin aspectos el cdigo de Apilar, por ejemplo, se vera ensuciado por el cdigo necesario para la traza y el control.
Extensin de aspectos

www.programemos.com Pgina 118/123

www.programemos.com

Para manejar la abstraccin y composicin de los conceptos entrecruzados, los aspectos pueden extenderse en una forma similar a las clases. Sin embargo, la extensin de aspectos agrega nuevas reglas. Un aspecto, abstracto o concreto, puede heredar de una clase e implementar un conjunto de interfaces. Heredar de una clase no le da al aspecto la habilidad de instanciarse con una expresin new . Una clase no puede heredar o implementar un aspecto. Tal situacin es considerada un error. Los aspectos puede heredar de otros aspectos, heredando atributos, mtodos y cortes. Una restriccin importante es que los aspectos solo pueden heredar aspectos abstractos. Se considera un error que un aspecto concreto herede de otro aspecto concreto. Como ejemplo podemos definir al aspecto TrazaPila en funcin de un aspecto abstracto TrazaSimple.

abstract aspect TrazaSimple{ abstract pointcut PuntosTraza(); before():PuntosTraza(){ System.out.println(Entrando + thisJoinPoint); } after():PuntosTraza(){ System.out.println(Retornando + thisJoinPoint); } } aspect TrazaPila extends TrazaSimple{ pointcut PuntosTraza():call(* Pila.*(..)); } Cdigo 6: Ejemplo de herencia en aspectos.
Privilegio de aspectos

El cdigo escrito en un aspecto est sujeto a las mismas reglas de acceso del cdigo Java para referenciar a miembros de clases o aspectos. Por ejemplo, un aspecto no puede referir a miembros con visibilidad package-protected sino est definido en el mismo paquete.
www.programemos.com Pgina 119/123

www.programemos.com

Existen algunas situaciones donde es necesario para los aspectos acceder a recursos privados o protegidos de otras clases. Para permitir esto se puede declarar al aspecto como privilegiado (privileged). Un aspecto privilegiado puede acceder a todos los atributos y mtodos, incluso a los privados. Por ejemplo: privileged aspect A { ... before(Pila p):Corte1(p){ ... p.capacidadMaxima=25; ... } ... } El aspecto A al ser declarado como privilegiado puede acceder al atributo privado capacidadMaxima de la clase Pila.
Precedencia de aspectos

Existen situaciones en donde los avisos de un aspecto deben preceder a los avisos de otro aspecto. Por tal motivo, un aspecto puede declarar que domina a otro aspecto estableciendo que los avisos definidos en l tienen prioridad sobre los avisos en el aspecto que domina. aspect <Identificador> dominates < PatrndeClase> {. . .} Como ejemplo, supongamos que tenemos definidos dos aspectos Precondicion y Trazado, y queremos que el aspecto Precondicion tenga mayor precedencia que el aspecto Trazado para que la traza se efecte slo si las precondiciones son satisfechas. Luego aspect Precondicion dominates Trazado {. . .} logra que el aspecto Precondicion, incluyendo sus avisos, tenga mayor precedencia que el aspecto Trazado y sus avisos sern ejecutados primero. La declaracin dominates forma parte de las reglas de precedencia de avisos, adems de otros elementos como la herencia de aspectos.Las reglas que determinan la precedencia de avisos son las siguientes: Si dos avisos estn definidos en diferentes aspectos entonces: Si el aspecto A domina al aspecto B entonces los avisos en A tienen precedencia sobre los avisos en B. En otro caso, si el aspecto A hereda del aspecto B entonces todos los avisos en A tienen precedencia sobre los avisos en B.
www.programemos.com Pgina 120/123

www.programemos.com

En otro caso, si no hay relacin entre los aspectos entonces es indefinido quien tiene mayor precedencia. Si dos avisos estn definidos en el mismo aspecto: Si ambos son avisos despus entonces el que est definido ltimo (segn la estructura lxica del programa) tiene mayor precedencia. En otro caso, aquel que aparezca primero tiene mayor precedencia. Cuando mltiples avisos se aplican a un mismo punto de enlace, el orden de resolucin se basa en la precedencia de los avisos.

BNF completa

La siguiente BNF describe la declaracin de aspectos en AspectJ agrupando todos los conceptos que vimos hasta ahora. <Aspecto>::=[privileged] aspect <Identificador> [extends <Nombre_Clase>] [implements <Lista_Clases>] [dominates <Lista_Clases>] { {<Atributos>} {<Mtodos>} {<Def_Cortes>} {<Introducciones>} {<Aviso>} } <Def_Cortes>::= abstract [<Modificadores>] pointcut <Identificador>(<Parametros_formales>); |
www.programemos.com Pgina 121/123

www.programemos.com

[<Modificadores>] pointcut <Identificador>(<Parametros_formales>):<Corte>; <Introducciones>::=<IntroduccionesdeAtributos> | <IntroduccionesdeMetodos> | <IntroduccionesdeMetodosAbstractos>| <IntroduccionesdeConstructores> <IntroduccionesdeAtributos>::= [<Modificadores>] <Nombre_Clase> <PatrondeClase>.<Identificador> [= <expresin>] ; <IntroduccionesdeMetodos>::= [<Modificadores>] <Nombre_Clase> <PatrondeClase>.<Identificador>(<Parametros_formales>) [ throws <Lista_Clases>] {<Cuerpo>} <IntroduccionesdeMetodosAbstractos>::= abstract [<Modificadores>] <Nombre_Clase> <PatrondeClase>.<Identificador>(<Parametros_formales>) [ throws <Lista_Clases>] ; <IntroduccionesdeConstructores>::= [<Modificadores>] <PatrondeClase>.new(<Parametros_formales>) [ throws <Lista_Clases>] {<Cuerpo>}

<Aviso>::=<Tipo_aviso> : <Corte> {<Cuerpo>} <Tipo_aviso>::= <Aviso_antes> | <Aviso_despues> | <Aviso_durante> <Aviso_antes>::= before (<Parametros_formales>) <Aviso_despues> ::= after (<Parametros_formales>) <Forma_terminacion> <Forma_terminacion>::= returning [(<Parametro_formal>) ] | throwing [(<Parametro_formal>) ] | <Aviso_durante>::= <Nombre_Clase> around (<Parametros_formales>) [ throws <Lista_Clases>] BNF 6: Definicin de aspectos
3.9.6 Evaluacin

En esta descripcin de AspectJ no han sido tratados detalles de implementacin para permitir una mejor comprensin y aprendizaje del lenguaje. Hemos priorizado la simpleza y forma general del lenguaje por sobre detalles de implementacin que oscurecen el entendimiento. Adems, no es necesario conocer a fondo estos detalles para iniciarse en la programacin de AspectJ. En s, describimos de AspectJ aquellos
www.programemos.com Pgina 122/123

www.programemos.com

conceptos necesarios para poder programar con aspectos por primera vez y/o entender la semntica de un programa escrito en AspectJ. En [35], la pgina oficial de AspectJ, se muestra la documentacin del lenguaje donde se describe informalmente los detalles de implementacin. La programacin en AspectJ es directa si el programador conoce el lenguaje Java. Los aspectos son muy similares a las clases, los avisos a los mtodos. Luego la declaracin de aspectos es sencilla, el programador con poco esfuerzo y sin mayores dificultades agrega aspectos a su implementacin con las ventajas que esto trae. Al ser una extensin compatible de Java los costos de aprendizaje son mnimos. AspectJ soporta la facilidad plug-in plug-out de aspectos. Los aspectos pueden agregarse o removerse de la funcionalidad bsica con slo incluirlos o no en la compilacin. As el programador puede intentar introducir aspectos en su aplicacin y de no satisfacerle los puede remover, manteniendo la aplicacin en su estado original. Uno de los puntos fuerte de AspectJ es la composicin de cortes a travs de operadores booleanos, la cual es a la vez simple y poderosa. Por lo tanto la expresividad del lenguaje es destacable.

www.programemos.com Pgina 123/123

También podría gustarte