Poa Borrador

2.348 visualizaciones

Publicado el

0 comentarios
0 recomendaciones
Estadísticas
Notas
  • Sé el primero en comentar

  • Sé el primero en recomendar esto

Sin descargas
Visualizaciones
Visualizaciones totales
2.348
En SlideShare
0
De insertados
0
Número de insertados
77
Acciones
Compartido
0
Descargas
13
Comentarios
0
Recomendaciones
0
Insertados 0
No insertados

No hay notas en la diapositiva.

Poa Borrador

  1. 1. Programación por Aspectos. Una Introducción Primer Borrador Pablo Figueroa y Alejandro Isaza 9 de mayo de 2006 1. Introducción A mediados de los 90 surgió la programación orientada a aspectos (POA), un nuevo paradigma de programación que ha logrado un nivel de desarrollo interesante y que ha generado expectativas importantes a nivel mundial. Este paradigma ofrece una nueva herramienta de modularización, el aspecto, junto con nuevas formas de relacionar módulos, por medio de los designadores de enlace; y mediante éstas herramientas provee formas novedosas de implementar aplicaciones que resultan ser altamente modulares. Sus conceptos tienen similaridad con conceptos en otros paradigmas de programación, como programación generativa [1], metaprogramación [4] o programación declarativa [6], aunque sus seguidores han encontrado una forma de diferenciar y darle carácter propio al desarrollo orientado por aspectos (DOA). Este artículo es una introducción al tema de desarrollo orientado por aspectos. Este trabajo ha surgido de grupos de discusión sobre el tema y del curso de pregrado que desarrollamos en el 2005 en la Universidad de los Andes, el cual está documentado en [2]. En esta introducción queremos mostrar una breve reseña histórica sobre el tema, los conceptos fundamentales alrededor de la DOA, definir sus características y proponer una forma de referirnos a sus conceptos en Castellano. Gracias a la disponibilidad de ambientes de desarrollo como AspectJ [3] es posible para cualquier lector con conocimientos en Java y en programación orientada por objetos desarrollar ejemplos de POA y aplicar sus conceptos fundamentales. Al final presentamos referencias adicionales al tema y un glosario de los conceptos que definimos, junto con los términos en inglés a los que corresponden en la literatura actual de aspectos. Dichos términos serán destacados durante el texto en negrita. Esperamos que esta introducción motive un estudio más profundo del tema por parte de los lectores y la exploración de las posibilidades de esta tecnología en proyectos reales. 2. Historia Desde los setentas, autores tan reconocidos como David Parnas han escrito sobre la importancia de modularizar un programa de software [5], y de las formas en las cuales se puede desarrollar esta 1
  2. 2. labor. En resumen, un programa puede dividirse en términos de las estructuras de datos que lo conforman, o de acuerdo a las tareas que soporta para sus usuarios (o requerimientos no funcionales definidos por sus diseñadores). Generalmente no se puede lograr ambas descomposiciones al mismo tiempo, lo cual genera problemas en el producto final, dependiendo del punto de vista desde el cual se analice el software. El término programación orientada por aspectos surgió a finales de 1995 en el grupo de trabajo de Gregor Kiczales en Xerox Palo Alto Research Center (PARC), un autodidacta, empresario y actualmente profesor de la Universidad de British Columbia. En esa época trabajaban en lo que ellos llamaban Open Implementations, trabajo que produjo un conjunto de lenguajes de propósito específico, de los cuales salió el concepto de Aspect Decomposition and Weaving (descomposición aspectual y tejido), el cual se redujo posteriormente a programación orientada por aspectos. Algunas ideas alrededor de este concepto fueron publicadas desde esta época, generalmente incompletas, lo que dió lugar a un conjunto temprano de seguidores como también a varios detractores, los cuales notaban claramente la debilidad e incompletitud de los conceptos. A principios de 1998 fue liberada la primera versión (0.1) de AspectJ, como una alternativa para POA genérica, a diferencia de los lenguajes de propósito específico que lo precedieron. Gracias al soporte gubernamental que recibió Kiczales el lenguaje pudo seguir evolucionando desde este mo- mento, convirtiendose en la prueba y ejemplo de los conceptos promovidos por POA. Hoy contamos con la versión 1.5 de AspectJ, estable y madura, y con una comunidad de trabajo activa alrededor del lenguaje. Además de AspectJ, existen otras plataformas más o menos maduras para iniciarse en el tema de aspectos. Composition Filters es un trabajo previo al de Kiczales, desarrollado por el grupo TRESE en el departamento de Ciencias de Computación de la Universidad de Twente, en Holanda. Éste ha sido adaptado a los conceptos de aspectos y es soportado sobre varios lenguajes tradicionales, como Java, C++ y Smalltalk y .NET. HyperJ es un proyecto de IBM que soporta un modelo por aspectos. Otras implementaciones son JBoss-AOP, Spring AOP, AspectC++, PHPAspect, AspectS y AspectXML1 . 3. Aproximaciones a los Aspectos En esta sección se incluyen varias formas complementarias de comprender el tema de programación orientada a aspectos. Empezamos con un ejemplo y complementamos esta visión con una descripción de los términos utilizados. Más adelante, comparamos el desarrollo por aspectos con el desarrollo de proyectos en organizaciones matriciales y con los conceptos de programación por objetos. 3.1. Un ejemplo de programa Un uso clásico de los conceptos en POA es la implementación de la funcionalidad de traza, la cual busca dejar un registro de las actividades desarrolladas en la ejecución de la aplicación, con 1 Una lista más completa puede ser encontrada en http://www.aosd.net/wiki/index.php?title=Tools_for_Developers 2
  3. 3. propósitos de auditoría o de depuración. Supongamos que el programa consta de las clases de la Figura 1. Figura 1: Clases en programa de ejemplo El programa principal hace uso de todos los servicios en las clases. Supongamos que deseamos generar un registro de auditoría como el que se muestra en el siguiente listado: Estoy en el metodo m1 de la clase ClaseA Estoy en el metodo m4 de la clase ClaseD ... Estoy en el metodo m5 de la clase ClaseE Si queremos agregar esta funcionalidad siguiendo el paradigma orientado por objetos (OO), es necesario tener acceso al código fuente del programa y cambiar el código en los métodos involucrados de tal manera que se genere el mensaje deseado. En el mejor de los casos, se puede utilizar alguna librería diseñada para generación de trazas, como java.util.logging o log4java. Un esquema de los cambios generados al código se pueden observar en la Figura 2, en donde las líneas punteadas llevan a un código de ejemplo que debe ser agregado en cada método. Este método de agregar traza es complejo y dificil de mantener, por diversas razones: el código de traza queda disperso por toda la aplicación, no se puede apagar dicha funcionalidad fácilmente, y es muy fácil olvidar el código adicional en nuevos métodos. Se dice que el código resultante es enmarañado, ya que cada método encapsula preocupaciones distintas: en este caso, el código que ya estaba ejecutando y el nuevo código para generar la traza. Un lenguaje orientado por aspectos permite hacer este tipo de cambios de una manera muy eficiente, sin tocar el código del programa original. Adicionalmente, en lenguajes como AspectJ, se pueden aplicar los cambios aún cuando no se tenga acceso al código fuente de las clases a las que se desea agregar traza. Utilizando las capacidades de la POA, es posible crear dos cosas: un consejo que encapsule el código que se quiere ejecutar en cada uno de los puntos donde se desee generar traza y un designador de enlace, que identifique en qué lugares se debe agregar el código del consejo. El código queda como se muestra en la Figura 3, en donde las líneas punteadas muestran en qué lugares se agrega el código del consejo de una manera automática. En este caso se puede observar las siguientes ventajas: 3
  4. 4. Figura 2: Cambios generados, paradigma OO Figura 3: Cambios generados, paradigma OA 4
  5. 5. No hay que modificar el código ya existente, para agregar algo que no está directamente relacionado con su funcionamiento actual. No es necesario contar con el código fuente del programa. Si se agregan nuevas clases o métodos al programa, sólo se debe cambiar el designador de enlace para que dichos métodos también generen traza. Sólo debe modificarse el consejo si se desea generar traza de una manera distinta. El código relacionado con la traza queda concentrado en un solo lugar, lo cual cumple con la filosofiá de modularidad básica. Se puede eliminar fácilmente la funcionalidad de traza, eliminando el aspecto. La ejecución del programa por aspectos es idéntica a la del programa por objetos, con la diferencia que el trabajo del desarrollador es mucho más eficiente y no se tiene que replicar código en varias partes del programa. El ambiente de programación por aspectos se encarga del proceso de tejido, el cual agrega la funcionalidad de traza al resto del código, aliviando al programador de dicha tarea. 3.2. Conceptos fundamentales En DOA, se supone que se puede dividir el software en preocupaciones, o asuntos que se desean resolver y que son claramente distinguibles: el almacenamiento de datos, una tarea del usuario, el tratamiento de seguridad, por ejemplo. El objetivo principal en DOA es expresar las distintas preo- cupaciones de una manera independiente y modular, aumentando los mecanismos de modularización existentes. Otro objetivo busca que se puedan agregar nuevos aspectos no previstos al código, lo cual denominamos transparencia. Se denominan puntos de enlace a todos aquellos elementos en un módulo que pueden relacionarse con otro. Algunos ejemplos de puntos de enlace son la entrada o salida de un método, la consulta o modificación de un atributo, la inicialización de un objeto o la generación de una excepción, aunque el conjunto de puntos varía dependiendo del lenguaje usado. Una lenguaje orientado a aspectos permite modularizar el código en términos de preocupaciones. Una preocupación en código se denomina un aspecto el cual define dónde se quiere agregar pedazos de código, denominados consejos, mediante designadores de enlace. Un designador de enlace permite generalmente cuantificar puntos de enlace por extensión, nombrando cada punto de enlace deseado, o por comprensión, describiendo una expresión que puede designar varios puntos de enlace. Hay ambientes de POA que consideran que todas las preocupaciones se aplican a un modulo domi- nante, el cual se denomina la descomposición dominante. Hay otros que consideran este esquema una tiranía, y consideran todas las preocupaciones al mismo nivel. Una vez se deciden los aspectos que hacen parte de una aplicación se procede a ejecutar su tejido, el cual es el proceso de com- poner el código de los distintos aspectos para poderlo ejecutar de una manera secuencial, como en cualquier programa procedimental. El proceso de tejido es generalmente en tiempo de compilación, aunque hay ambientes de desarrollo que hacen operaciones de tejido en ejecución. El proceso de tejido genera un código enmarañado, el cual se esconde del programador por aspectos. 5
  6. 6. 3.3. Una interpretación organizacional Una forma de comprender lo que agrega la POA a metodos tradicionales de programación como la programación orientada por objetos es observando las caracterísiticas de estructuras organizacionales matriciales. En dichas organizaciones, coexisten jerarquias por proyectos y por áreas de producción o de servicio, como una manera de atender mejor a los clientes a la vez que se optimizan costos y procedimientos. Los recursos se organizan dentro de la matriz proyectos versus áreas, y cada recurso puede ser requerido en varios proyectos como en varias áreas. Un empleado de dicha organización debe preocuparse por tareas en varios aspectos, bien sea relacionados a un proyecto o relacionados a un área del negocio. Los aspectos en software pueden asemejarse a recursos especializados en áreas del negocio, los cuales pueden desempeñarse en varias aplicaciones, o quot;proyectosquot;. Estos recursos pueden utilizarse en nuevos proyectos, y su conocimiento no depende de ningún proyecto en particular. Su intervención en cada proyecto está dada por su flujo de trabajo, el cual determina en qué momento es indispensable la intervención de dicho recurso. La posibilidad de tener recursos que atienden un mismo aspecto en varios proyectos ha probado ser benéfica en este tipo de aplicaciones. 3.4. Una interpretación evolutiva desde objetos El concepto de modularidad es fundamental en la programación orientada por objetos (POO), implementado mediante el concepto de clase, como también lo son las formas de combinar dichos módulos. La POO ofrece dos formas fundamentales de relación entre clases: delegación y herencia. En delegación, una clase contiene objetos de otras clases, a los cuales puede delegar parte o la totalidad de sus responsabilidades. En herencia, la definición de una clase B puede agregar atributos o métodos a la definición de otra clase A, siendo posible además reemplazar instancias de A por instancias de B. La POA crea un nuevo concepto de módulo (el aspecto) y formas de relacionar estos nuevos módulos con clases, mediante el concepto de puntos de enlace. En lenguajes como AspectJ se cuenta con una gran variedad de puntos de enlace, que permiten agregar código antes y despues de métodos, tanto en su llamado como en su ejecución, agregar atributos y métodos a una clase o agregar código a ciertos métodos dentro del flujo de ejecución. Aunque existen implementaciones de ambientes para POA que no son orientados por objetos, los que están implementados sobre ambientes de POO permiten una gran variedad de formas para modularizar y componer código. 4. Comparación con otros paradigmas Existen varias ideas en el área de desarrollo de software que dieron origen o que se relacionan con el concepto de aspectos. Acá analizamos las siguientes: programación por objetos, programación generativa, metalenguajes y programación declarativa. Como ya describimos en la sección 3.4, la POA agrega nuevas formas de modularización y compo- 6
  7. 7. sición. Algunas de estas nuevas oportunidades son: Agregar código a ciertos métodos. Es posible agregar consejos a uno o más métodos a la vez, independientemente de las relaciones de herencia existentes entre las clases de dichos métodos. Modificar una clase. Es posible agregar métodos y atributos a una clase sin crear nuevos tipos. Esto permite modularizar responsabilidades disyuntas dentro de una clase, sin tener que crear muchos tipos en el programa (este problema es generalmente denominado explosión de clases). Agregar código y comportamiento sin tener que prever con anterioridad dónde, lo cual hace más comprensible el código de la descomposición dominante. La programación generativa busca, como su nombre lo indica, generar código desde descripciones de alto nivel, concepto relacionado con el de lenguajes de dominio específico [1]. Existen muchos puntos comunes entre programación generativa y aspectos. Es posible, por ejemplo, describir los mecanismos de un lenguaje de aspectos en un lenguaje de dominio específico (el dominio de los aspectos) y generar el código correspondiente en un lenguaje convencional (de hecho, hay varias implementaciones de lenguajes de aspectos que funcionan de esta manera). Hay también varias diferencias: algunos lenguajes de POA permiten hacer tejido en tiempo de ejecución, lo cual no es posible en programación generativa. Es tambien importante en un lenguaje de POA definir un conjunto claro de mecanismos de modularización y esconder los mecanismos de tejido, los cuales son visibles en un ambiente generativo. En general, la programación generativa es un mecanismo de implementación para ambientes de POA (no es único), y un ambiente de POA es mucho mas específico en sus métodos de composición y modularización que un ambiente generativo. Existe también una relación estrecha entre el paradigma de POA y los metalenguajes. Un lenguaje de programación con caracterísiticas de metalenguaje permite escribir sentencias que se refieren al código escrito, o en otras palabras a las mismas estructuras de programación o sentencias utiliza- das. Existen muchos lenguajes de programación que tienen capacidades de metalenguajes, como por ejemplo Smalltalk y Java, con sus capacidades de introspección. Es posible en general describir los mecanismos de aspectos mediante metalenguajes, debido a la gran versatilidad de dichos ambientes. Sin embargo, existen dos problemas con este esquema: lo enmarañado del codigo y las amplias posi- bilidades existentes en los metalenguajes. Aunque se pueden implementar los mecanismos de POA mediante un metalenguaje, en general el código resultante es complicado de escribir y compren- der, por lo que un lenguaje de POA generalmente ofrece nueva sintaxis específica a sus propósitos. Por otra parte, un metalenguaje puede hacer muchas otras cosas adicionales a las incluidas como conceptos de POA, lo cual los hace ambientes de propósito general. POA puede verse como una aplicación limitada de las capacidades de un metalenguaje, aunque con una sintaxis que le facilita su utilización a un programador. 5. Referencias Adicionales Por completar 7
  8. 8. 6. Conclusiones De la misma manera como Smalltalk generó un gran interés por la programación orientada por obje- tos a principios de los 70, AspectJ ha movido la comunidad internacional alrededor de los conceptos de orientación por aspectos. La programación por aspectos ofrece un conjunto de herramientas adi- cionales que permiten modularizar software mediante varios criterios, no únicamente los dominantes, lo cual permite separar mejor las distintas facetas del software. El ambiente provisto por AspectJ es lo suficientemente maduro para que programadores en Java lo incluyan en sus desarrollos. Cree- mos que el uso de este tipo de herramientas pueden facilitar el desarrollo de aplicaciones, e influir positivamente en la calidad del producto final. 7. Glosario Aspecto (aspect). Un aspecto es la descripción en un lenguaje de programación de una preocu- pación en el software. Código enmarañado (code tangling). El resultado en código de tener preocupaciones disper- sas. Composición (composition). Es el proceso de unir componentes de alguna manera. Los lengua- jes como AspectJ agregan nuevos métodos para crear composiciones sobre los existentes en lenguajes orientados por objetos. Consejo (advice). Cada uno de los “métodos” de un aspecto. Cuantificación por extensión/comprensión (quantification). Un designador de enlace pue- de nombrar puntos de enlace bien sea por extensión o comprensión. Por extensión significa que deben nombrarse uno a uno todos los puntos de enlace. Por comprensión significa que pueden utilizarse reglas o patrones para que el sistema busque todos los puntos de enlace que cumplen con dicho patrón. Un ejemplo de regla en AspectJ es public * *.set*(..), la cual va a incluir todos los métodos públicos que comiencen con set. Descomposición dominante (dominant decomposition). En un programa orientado por ob- jetos existe solo una descomposición. Una descomposición dominante en un lenguaje por as- pectos corresponde generalmente al conjunto de módulos a los cuales se unen los aspectos. Dichos módulos son importantes porque definen en cierta medida la estructura dominante del programa. Designador de enlace (point cut designator). Es la forma en la cual un aspecto se refiere a los puntos de enlace en los cuales quiere agregar funcionalidad. Envolver antes/despues (wrapping, before/after). Un método para agregar código alrededor de un método. Preocupación (concern). Es una característica del software. Puede corresponder a un requeri- miento funcional o no funcional, o a alguna labor interna que debe desarrollar el software para cumplir con su funcionalidad. Un ejemplo de preocupación es la persistencia de los datos en el programa, o la autenticación de usuarios. 8
  9. 9. Preocupaciones dispersas (crosscutting concerns). Es la característica del software tradicio- nal de tener mezclado el código que soluciona diversas preocupaciones. Programación generativa (Generative programming). Transforma representaciones de alto nivel de un programa a código de “bajo” nivel. Puntos de enlace (join points). Son los lugares en los cuales se puede agregar funcionalidad, correspondiente a preocupaciones no planeadas previamente. Cada lenguaje de programación por aspectos define un conjunto de puntos de enlace, los cuales pueden ser estáticos (parte de la sintaxis del programa) o dinámicos (parte del estado en ejecución del programa). Ejemplos de puntos de enlace estáticos son cualquier método en una clase (paint() en un Applet, por ejemplo). Ejemplos de puntos de enlace dinámicos son el cambio de una variable a un valor en un rango, o la llamada de un método dentro de otro. Tejido (weaving). Es el proceso que realiza el compilador (o ambiente de ejecución) de un lenguaje por aspectos para agregar los consejos a los puntos de enlace correspondientes. Transparencia (obliviousness). Se refiere al hecho de no identificar dónde se agrega el código de los aspectos. El objetivo principal es poder agregar funcionalidad en el futuro sin tener que planearla por anticipado. Por ejemplo, un mecanismo de listeners permite agregar código a una clase, pero hay que planearlo por anticipado, y se nota en el código por los métodos necesarios para agregar y eliminar listeners (por lo tanto no es transparente). Un mecanismo transparente, como los usados en AspectJ, permiten agregar funcionalidad de una manera transparente. Traza (log, trace) . Registro de las actividades desarrolladas en la ejecución de la aplicación, con propósitos de auditoría o de depuración. Referencias [1] Krzysztof Czarnecki and Ulrich W. Eisenecker. Generative Programming: Methods, Tools, and Applications. Addison–Wesley, 2000. [2] Pablo Figueroa. Teaching aspects to undergraduates. In AOSD 2006 Workshop. Aspects in Teaching, 2006. [3] AspectJ Group. The aspectj project at eclipse.org. http://www.eclipse.org/aspectj/, 2006. [4] Gregor Kiczales, Jim des Rivières, and Daniel G. Bobrow. The Art of the Metaobject Protocol. MIT Press, 1991. [5] D. L. Parnas. On the criteria to be used in decomposing systems into modules. Commun. ACM, 15(12):1053–1058, 1972. [6] Leon Sterling and Ehud Shapiro. The Art of Prolog. MIT Press, 1994. 9

×