Está en la página 1de 7

Programacin Orientada a Aspectos (AOP)

Por Nicols Kicillof

Introduccin Los conceptos y tecnologas reunidos bajo el nombre "programacin orientada a aspectos" (AOP, por las siglas de Aspect-Oriented Programming; o AOSD, por Aspect-Oriented Software Development) buscan resolver un problema identificado hace tiempo en el desarrollo de software. Se trata del problema de la separacin de incumbencias (separation of concerns). AOP no es el nico intento por solucionar este problema, del que voy a hablar a continuacin: hay varias propuestas, muchas de las cuales se agrupan (junto con AOP) en el campo de estudio denominado ASoC (Advanced Separation of Concerns). Separacin de Incumbencias El principio de separacin de incumbencias fue identificado en la dcada de 1970 (1), plantea que un problema dado involucra varias incumbencias que deben ser identificadas y separadas. Las incumbencias son los diferentes temas o asuntos de los que es necesario ocuparse para resolver el problema. Una de ellas es la funcin especfica que debe realizar una aplicacin, pero tambin surgen otras como por ejemplo distribucin, persistencia, replicacin, sincronizacin, etc. Separando las incumbencias, se disminuye la complejidad a la hora de tratarlas y se puede cumplir con requerimientos relacionados con la calidad como adaptabilidad, mantenibilidad, extensibilidad y reusabilidad. El principio puede aplicarse de distintas maneras. Por ejemplo, separar las fases del proceso de desarrollo puede verse como una separacin de actividades de ingeniera en el tiempo y por su objetivo. Definir subsistemas, objetos y componentes son otras formas de poner en prctica el principio de separacin de incumbencias. Por eso podemos decir que se trata de un principio rector omnipresente en el proceso de desarrollo de software. Las tcnicas de modelado que se usan en la etapa de diseo de un sistema se basan en partirlo en varios subsistemas que resuelvan parte del problema o correspondan a una parte del dominio sobre el que trata. Estas tcnicas sufren en su mayora la llamada "tirana de la descomposicin dominante" que consiste en guiarse al modelar, implcita o explcitamente, por una visin jerrquica determinada de la organizacin del sistema. La desventaja de estas particiones es que muchas de las incumbencias a tener en cuenta para cumplir con los requerimientos (en particular, habitualmente, las incumbencias no funcionales) no suelen adaptarse bien a esa descomposicin, como veremos ms adelante. Las construcciones provistas por los lenguajes de programacin, que fueron creados para implementar los modelos generados por las tcnicas de diseo existentes, reproducen las jerarquas y, por lo tanto, comparten el defecto explicado en el prrafo anterior. En el paradigma de programacin imperativa, la descomposicin consiste en identificar procedimientos que resuelvan parte del problema, y la jerarqua se da en el rbol de ejecucin, segn el cual los procedimientos se invocan unos a otros. En el caso de la programacin orientada a objetos, la jerarqua generada en la etapa de diseo suele plasmarse en las relaciones de herencia o de composicin entre objetos. Por ejemplo, algunos patrones de diseo de uso habitual como observador (observer), visitante (visitor) y mediador (mediator) (2) exhiben estos problemas, ya que para aplicarlos es necesario adaptar a ellos ms de una clase. El problema aparece cuando una incumbencia afecta a distintas partes del sistema que no aparecen relacionadas en la jerarqua. En ese caso, la nica solucin suele ser escribir cdigo repetido que resuelva esa incumbencia para cada subsistema. Un ejemplo clsico de la programacin orientada a aspectos es el de distintos mtodos de un

sistema de edicin de grficos que, luego de modificar la representacin interna, terminan actualizando su vista en pantalla, como se muestra en la Figura 1.

Figura

1:

Incumbencia

diseminada

Estas responsabilidades, que aparecen diseminadas en el cdigo atravesando partes del sistema no relacionadas en el modelo, se denominan incumbencias transversales (crosscutting concerns). Incumbencias Transversales Otro ejemplo, tambin clsico, de incumbencias transversales es el logging o registro de la actividad de una aplicacin. En varios puntos de ejecucin, que podran pertenecer a elementos del programa disconexos, queremos invocar un mtodo que registra en un archivo de texto o en una base de datos el hecho de que se ha llegado a ese punto. Las consecuencias directas de estas incumbencias transversales son el cdigo disperso y enredado (scattering and tangling). Se habla de cdigo disperso cuando un mismo servicio es invocado de manera similar desde muchas partes del programa, como en el ejemplo que vemos en la Figura 2. Aqu cada barra representa un mdulo del sistema, las lneas de cdigo que invocan el servicio de logging estn en rojo.

Figura

2:

Logging

en

Apache

Tomcat

[Kiczales

2001]

Si una misma operacin tiene que acceder a varios servicios (logging, locking, presentacin, transporte, autenticacin, seguridad, etc), adems de cumplir con su funcin especfica, estamos ante una muestra de cdigo enredado. La fuente de estos problemas es que en realidad cada aplicacin tiene una poltica sobre dnde se requiere cada uno de estos servicios; pero esa poltica no es explcita, est oculta como parte de la estructura del programa. Esto hace que sea difcil de entender, razonar sobre ella y mantenerla. La solucin que propone la comunidad de AOP es modularizar las incumbencias transversales, justamente esa es la definicin de aspecto: una incumbencia transversal modularizada. Aspectos Ya sabemos cul es la idea detrs de un aspecto, veamos ahora cmo se llevan a la prctica. Empecemos por ver la propuesta de AOP para resolver la dispersin de la Figura 1, que se muestra en la Figura 3. Lo que se hizo fue definir un aspecto (pronto hablaremos de las partes que lo conforman) que indica que se debe ejecutar la instruccin Display.update(); al terminar la invocacin a cualquier mtodo cuyo nombre comienze con set, de una subclase de FigureElement. La notacin usada est basada en AspectJ (3). Para entender cmo se aplica un aspecto, tenemos que empezar por el concepto de punto de unin (join point). Los puntos de unin son puntos en la ejecucin de un programa. Por ejemplo, "al invocar al mtodo Line.getP1() por cuarta vez". Es importante recalcar que los puntos de unin no son posiciones en el cdigo fuente (ni dentro de una instruccin, ni entre instrucciones), sino en la ejecucin del programa. La frase anterior habla de la cuarta invocacin de un mtodo en una ejecucin, y esto no corresponde a un punto en el cdigo. En distintas ejecuciones podra variar qu instruccin es la que invoca por cuarta vez a Line.getP1(), por ejemplo, se podra llamar a este mtodo dentro de un ciclo while (i<j) Line.getP1(); Dependiendo de los valores de i y j, y de lo que haya pasado antes en esta ejecucin, la cuarta llamada a este mtodo podra ser en esta instruccin o en otra.

Figura

3:

Aspecto

de

actualizacin

de

pantalla

Ahora pasemos a hablar de un concepto un poco ms complicado que el de punto de unin, que es el de pointcut. Un pointcut es un predicado, una afirmacin que es cumplida por un conjunto de puntos de unin. En nuestro ejemplo de la Figura 3, aparece un pointcut: que vamos a analizar por partes. call(void FigureElement+.set*(..)) significa "al invocar (call) cualquier mtodo de la clase FigureElement o de una sublclase (+), cuyo nombre comience con set (set*), que tenga void como tipo de retorno y cualquier cantidad de parmetros (..)". El siguiente fragmento es fcil de comprender: call(void FigureElement.moveBy(int, int)). El operador de disyuncin (||) se usa para unir estos dos pointcuts y formar uno nuevo. Los puntos de unin que cumplan el pointcut compuesto sern aquellos que cumplan uno u otro de los dos. Adems de call hay otros constructores de pointcuts, como get (al leer el valor de una variable), set (al modificarlo), cflowbelow (dentro del flujo de control), initialization (al inicializar un objeto), etc. Y tambin formas de acceder al contexto como target (clase que recibe el mensaje), args (argumentos de una llamada), etc. Los pointcuts son parte de un aspecto, indican dnde (en qu puntos de unin) se va a aplicar. La otra parte es lo que se llama un consejo (advice), que indica qu es lo que hay que hacer en esos puntos de unin. En la Figura 3, el consejo dice que hay que agregar la instruccin Display.Update(); despus (after) de cada uno de los puntos de unin indicados por el pointcut. En vez de after, se podra haber puesto before (antes), after returning (despus de ejecutar un mtodo en forma normal), after throwing (despus de arrojar una excepcin) o around (en lugar de ejecutar el punto de unin). El mecanismo por el cual se combinan los aspectos con el cdigo base se llama entretejido (weaving), y puede hacerse en distintos momentos de la vida de un programa. Una posibilidad es llevar a cabo el entretejido en una etapa de precompilacin: se toma el cdigo base y los aspectos, y se produce nuevo cdigo fuente con el resultado del entretejido, insertando los consejos en los puntos de unin correspondiente. Tambin se puede hacer durante la compilacin, generando cdigo objeto que cumpla la funcionalidad base ms la de los aspectos. Y otra alternativa es el llamado entretejido dinmico, por el cual se controla la ejecucin del programa y, cada vez que se llega a un punto de unin incluido en un pointcut de un aspecto, se ejecuta el consejo asociado.

En este ejemplo tan sencillo que vimos, aparecen ya las dos ideas ms poderosas que hay detrs de los aspectos: prescindencia (obliviousness) y cuantificacin (quantification). Ambas estn asociadas al mecanismo de construccin de pointcuts. La prescindencia se refiere a que el programador encargado de implementar una funcionalidad especfica no debera estar al tanto de las otras dimensiones que pueden afectar su cdigo. La cuantificacin es la posibilidad de indicar en qu puntos de unin se aplicar un aspecto, sin necesidad de enumerarlos uno por uno. Prescindencia y Cuantificacin La prescindencia se corresponde con el principio de abstraccin y encapsulamiento omnipresente en la ingeniera de software, es bsica para poder mantener la separacin de incumbencias. Si se hiciera necesario que un programador tuviera en cuenta, al escribir su cdigo, cules sern los aspectos que se le aplicarn, no estaramos logrando la separacin de incumbencias que planteamos como objetivo inicial. Por ejemplo, no podramos cambiar a qu puntos de unin afectar un aspecto, sin modificar el cdigo base. La cuantificacin tambin es esencial al trabajar con aspectos. Recuerden que hablando de incumbencias transversales dijimos que cada sistema tena una poltica sobre dnde se requera entrelazar un servicio. Como los aspectos pretenden modularizar las incumbencias transversales, la poltica debe hacerse explcita y formar parte del aspecto. En la notacin que vimos, la cuantificacin est dada por el lenguaje de definicin de pointcuts y, en particular, por los comodines (*, +, ..), que permiten referirse de forma genrica un grupo de puntos de unin. Es el equivalente a definir un conjunto por comprensin, diciendo qu propiedad cumplen todos sus miembros, en lugar de hacerlo por extensin, listndolos. En algunas supuestas implementaciones de AOP, se requiere que el programador del cdigo base indique de alguna forma en su programa, en cada punto de unin, qu aspectos deben insertarse en ese lugar. Este mecanismo viola tanto la prescindencia como la cuantificacin, porque el programador no puede ignorar los aspectos y debe enumerar los puntos de unin. Otras implementaciones brindan herramientas para que, por fuera del cdigo, se seale en forma interactiva dnde se espera que se entrelace un aspecto. Este mtodo es ms limpio que el anterior desde el punto de vista de la prescindencia, porque la tarea puede llevarse a cabo independientemente de la escritura del programa. Pero comparte con el anterior la violacin del principio de cuantificacin: la poltica no se hace explcita ni se modulariza como parte de los aspectos, est dada por las acciones del encargado de marcar a mano los puntos de unin. Incluso si el resultado de esas acciones se almacena en algn formato, los puntos de unin aparecen listados y no definidos por sus propiedades. Aspectos y .NET El desarrollo de software orientado a aspectos todava se encuentra en un estado incipiente. La mayora de las implementaciones es de carcter experimental. La tecnologa no ha sido hasta ahora claramente adoptada por la industria, aunque importantes empresas relacionadas con el desarrollo de software estn financiando proyectos ambiciosos de AOP. Una de las razones para la falta de adopcin puede encontrarse en la dificultad que introducen los aspectos para razonar sobre los programas. Muchas de las tcnicas de diseo y de las buenas prcticas de codificacin actuales tienen por objetivo garantizar la composicionalidad del razonamiento sobre programas: no hace falta leer el cdigo entero para entender qu es lo que hace un fragmento, se pueden extraes conclusiones sobre el comportamiento local y esas conclusiones siguen siendo vlidas sin importar cmo se inserte el fragmento en un sistema mayor. Pero los aspectos pueden invalidar esta premisa, ya que permiten modificar "desde afuera" el comportamiento de una parte del programa. Existen algunas propuestas para solucionar este problema de AOP y proyectos completos de ASoC que constituyen alternativas al enfoque de aspectos, creadas con el objetivo especfico de evitar alterar el comportamiento local o de hacerlo en forma predecible. Hasta el momento ninguna de estas variantes ha cobrado la relevancia suficiente como para mover a la

comunidad

de

AOSD

en

esa

direccin.

Otro inconveniente que atenta contra la adopcin generalizada de AOP es la reusabilidad reducida. El principio de prescindencia garantiza el desacoplamiento en un solo sentido: el cdigo base no depende de los aspectos. Pero las notaciones de cuantificacin y acceso al contexto como las que vimos atan los aspectos a una aplicacin en particular u obligan al programador a seguir convenciones de codificacin, lo cual va en contra de la prescindencia. Esto se debe al uso de comodines basados en el nombre que tienen los identificadores del cdigo base. Siguiendo el ejemplo de la Figura 3, los programadores estaran obligados a poner nombres que comenzaran con set a todos los mtodos cuya tarea fuera la de cambiar el valor de una propiedad que alterara la presentacin en pantalla. O, alternativamente, hara falta modificar la definicin del pointcut para adaptarla a otra convencin (por ejemplo, si en una aplicacin el nombre de estos mtodos comenzara con update). Evitar estos problemas es el objetivo de nuestro proyecto SetPoint (4) que incluye un desarrollo sobre la plataforma Microsoft .NET. Adems del nuestro, existen otros proyectos para agregar, de uno u otro modo, aspectos a .NET. Teniendo en cuenta que una de las grandes ventajas de esta tecnologa es la de ser multilenguaje, es obvia la importancia que tiene, para toda propuesta sobre .NET respetar este rasgo. Esta premisa inclina la balanza hacia las tcnicas de entretejido dinmico; las variantes estticas son altamente dependientes del lenguaje, porque implican preprocesar o compilar el cdigo base. Esto complica un poco la implementacin, porque el entretejido dinmico implica, la mayora de las veces, modificar la mquina virtual o el soporte de tiempo de ejecucin de los lenguajes (en este caso, el CLR). Tal vez por eso, como podrn observar en la pgina de proyectos investigacin de AOSD (5) , existen varios basados en trabajar con un nico lenguaje .NET (en general, C#, como es de esperar) o con un conjunto limitado de ellos. Un ejemplo interesante de la aplicacin de las ideas de AOP al desarrollo de software la ofrecen algunas caractersticas de ASP.NET. En particular, el mecanismo de validacin de formularios y el de autenticacin. En ambos casos, podemos hablar de separacin de incumbencia e incluso de cierto grado de prescindencia, ya que el programador de la funcionalidad bsica no debe preocuparse por implementar estas incumbencias. La validacin de los valores ingresados por el usuario en una pgina est a cargo de controles que encierran esa tarea y cuyo uso no se solicita en los campos a ser validados, sino en las propiedades del control de validacin mismo. La autenticacin de usuarios para todas las pginas de una aplicacin tampoco se hace pgina por pgina, sino a travs de un archivo de configuracin. En ambos casos, el entrelazado est a cargo del framework .NET. Las caractersticas enumeradas distan de ser implementaciones de AOP por su falta de generalidad. Los mecanismos de AOP deben permitir a un programador definir sus propios aspectos y no limitarlo a un conjunto reducido de funcionalidades. Adems, aunque comparten con los aspectos la ventaja de la prescindencia, no ofrecen la de la cuantificacin. Los controles de validacin requieren indicar explcitamente el campo que deben verificar. La autenticacin brinda una forma de cuantificacin universal: afecta, en principio, a todas las pginas de una aplicacin; pero si se pretende acotar su alcance, se debe caer nuevamente en la enumeracin. A pesar de no tratarse de aspectos en todo su esplendor, sirven como ejemplos del trabajo que pueden ahorrar estas tcnicas en el proceso de desarrollo. Tambin podran ofrecerse como ejemplo los .NET Enterprise Services (como otras alternativas de middleware), ofreciendo servicios a los programadores de componentes: seguridad basada en roles, colas de mensajes, eventos, transacciones, etc. Todos ellos ofrecen alguna forma de prescindencia, pero no incluyen notaciones que sirvan para cuantificacin, siempre hay que indicar caso por caso a qu componentes afectan.

(1)

E.

W.

Dijkstra,

Discipline

of

Programming.

Prentice

Hall,

1976.

(2) E. Gamma, R. Helm, R. Johnson y J. Vlissides, Design patterns: Elements of Reusable Object-Oriented Software, Addison-Wesley, 1995. (3) G. Kiczales, E. Hilsdale, J. Hugunin, M. Kersten, J. Palm y W. Griswold. An Overview of AspectJ, ECOOP 2001 (5) http://www.dc.uba.ar/people/proyinv/setpoint (4) http://aosd.net/technology/research.php

Nicols Kicillof es Profesor Adjunto del Departamento de Computacin de la Facultad de Ciencias Exactas y Naturales de la Universidad de Buenos Aires, donde dicta la materia Paradigmas de Lenguajes de Programacin. Sus campos de investigacin son la Ingeniera de Software y los lenguajes de programacin. Tiene una vasta experiencia profesional liderando equipos de consultora y desarrollo, especialmente en plataformas Microsoft.

También podría gustarte