SlideShare una empresa de Scribd logo
1 de 7
Descargar para leer sin conexión
Programación Orientada a Aspectos (AOP)
Por Nicolás Kicillof



Introducción

Los conceptos y tecnologías reunidos bajo el nombre quot;programación orientada a aspectosquot;
(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 separación de incumbencias (separation of concerns).
AOP no es el único intento por solucionar este problema, del que voy a hablar a continuación:
hay varias propuestas, muchas de las cuales se agrupan (junto con AOP) en el campo de
estudio denominado ASoC (Advanced Separation of Concerns).

Separación de Incumbencias

El principio de separación de incumbencias fue identificado en la década 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 función específica que debe realizar una aplicación,
pero también surgen otras como por ejemplo distribución, persistencia, replicación,
sincronización, 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 separación de actividades de ingeniería en el tiempo y por
su objetivo. Definir subsistemas, objetos y componentes son otras formas de poner en práctica
el principio de separación de incumbencias. Por eso podemos decir que se trata de un principio
rector      omnipresente      en      el     proceso    de     desarrollo     de     software.

Las técnicas de modelado que se usan en la etapa de diseño 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 técnicas sufren en su mayoría la llamada quot;tiranía de la
descomposición dominantequot; que consiste en guiarse al modelar, implícita o explícitamente, por
una visión jerárquica determinada de la organización 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   descomposición,     como     veremos     más      adelante.

Las construcciones provistas por los lenguajes de programación, que fueron creados para
implementar los modelos generados por las técnicas de diseño existentes, reproducen las
jerarquías y, por lo tanto, comparten el defecto explicado en el párrafo anterior. En el
paradigma de programación imperativa, la descomposición consiste en identificar
procedimientos que resuelvan parte del problema, y la jerarquía se da en el árbol de ejecución,
según el cual los procedimientos se invocan unos a otros. En el caso de la programación
orientada a objetos, la jerarquía generada en la etapa de diseño suele plasmarse en las
relaciones de herencia o de composición entre objetos. Por ejemplo, algunos patrones de
diseño de uso habitual como observador (observer), visitante (visitor) y mediador (mediator) (2)
exhiben estos problemas, ya que para aplicarlos es necesario adaptar a ellos más de una
clase.

El problema aparece cuando una incumbencia afecta a distintas partes del sistema que no
aparecen relacionadas en la jerarquía. En ese caso, la única solución suele ser escribir código
repetido     que     resuelva      esa      incumbencia       para      cada      subsistema.

Un ejemplo clásico de la programación orientada a aspectos es el de distintos métodos de un
sistema de edición de gráficos que, luego de modificar la representación 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 código atravesando partes del
sistema no relacionadas en el modelo, se denominan incumbencias transversales (crosscutting
concerns).

Incumbencias Transversales

Otro ejemplo, también clásico, de incumbencias transversales es el logging o registro de la
actividad de una aplicación. En varios puntos de ejecución, que podrían pertenecer a
elementos del programa disconexos, queremos invocar un método 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 código disperso y
enredado (scattering and tangling). Se habla de código 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 módulo del sistema, las líneas de código
que invocan el servicio de logging están en rojo.
Logging
Figura       2:                     en       Apache        Tomcat        [Kiczales       2001]


Si una misma operación tiene que acceder a varios servicios (logging, locking, presentación,
transporte, autenticación, seguridad, etc), además de cumplir con su función específica,
estamos         ante         una         muestra       de          código         enredado.

La fuente de estos problemas es que en realidad cada aplicación tiene una política sobre
dónde se requiere cada uno de estos servicios; pero esa política no es explícita, está oculta
como parte de la estructura del programa. Esto hace que sea difícil de entender, razonar sobre
ella                                      y                                        mantenerla.

La solución que propone la comunidad de AOP es modularizar las incumbencias transversales,
justamente esa es la definición de aspecto: una incumbencia transversal modularizada.

Aspectos

Ya sabemos cuál es la idea detrás de un aspecto, veamos ahora cómo se llevan a la práctica.
Empecemos por ver la propuesta de AOP para resolver la dispersión 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 instrucción Display.update(); al terminar
la invocación a cualquier método cuyo nombre comienze con set, de una subclase de
                    La     notación     usada       está    basada      en    AspectJ
FigureElement.                                                                             (3).

Para entender cómo se aplica un aspecto, tenemos que empezar por el concepto de punto de
unión (join point). Los puntos de unión son puntos en la ejecución de un programa. Por
ejemplo, quot;al invocar al método Line.getP1() por cuarta vezquot;. Es importante recalcar que los
puntos de unión no son posiciones en el código fuente (ni dentro de una instrucción, ni entre
instrucciones), sino en la ejecución del programa. La frase anterior habla de la cuarta
invocación de un método en una ejecución, y esto no corresponde a un punto en el código. En
distintas ejecuciones podría variar qué instrucción es la que invoca por cuarta vez a
Line.getP1(), por ejemplo, se podría llamar a este método 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
ejecución, la cuarta llamada a este método podría ser en esta instrucción o en otra.
Figura         3:        Aspecto          de         actualización          de         pantalla


Ahora pasemos a hablar de un concepto un poco más complicado que el de punto de unión,
que es el de pointcut. Un pointcut es un predicado, una afirmación que es cumplida por un
conjunto de puntos de unión. En nuestro ejemplo de la Figura 3, aparece un pointcut: que
vamos a analizar por partes. call(void FigureElement+.set*(..)) significa quot;al invocar (call)
cualquier método 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 parámetros (..)quot;. El
siguiente fragmento es fácil de comprender: call(void FigureElement.moveBy(int, int)). El
operador de disyunción (||) se usa para unir estos dos pointcuts y formar uno nuevo. Los puntos
de unión que cumplan el pointcut compuesto serán aquellos que cumplan uno u otro de los
dos.

Además 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 también formas de acceder al contexto como target (clase que
recibe       el    mensaje),               (argumentos     de      una    llamada),      etc.
                                  args

Los pointcuts son parte de un aspecto, indican dónde (en qué puntos de unión) 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 unión. En la Figura 3, el consejo dice que hay que agregar la instrucción
Display.Update(); después (after) de cada uno de los puntos de unión indicados por el
pointcut. En vez de after, se podría haber puesto before (antes), after returning (después de
ejecutar un método en forma normal), after throwing (después de arrojar una excepción) o
               (en       lugar      de       ejecutar       el      punto       de       unión).
around

El mecanismo por el cual se combinan los aspectos con el código 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 precompilación: se toma el código base y los
aspectos, y se produce nuevo código fuente con el resultado del entretejido, insertando los
consejos en los puntos de unión correspondiente. También se puede hacer durante la
compilación, generando código objeto que cumpla la funcionalidad base más la de los
aspectos. Y otra alternativa es el llamado entretejido dinámico, por el cual se controla la
ejecución del programa y, cada vez que se llega a un punto de unión incluido en un pointcut de
un          aspecto,          se         ejecuta        el         consejo          asociado.
En este ejemplo tan sencillo que vimos, aparecen ya las dos ideas más poderosas que hay
detrás de los aspectos: prescindencia (obliviousness) y cuantificación (quantification). Ambas
están asociadas al mecanismo de construcción de pointcuts. La prescindencia se refiere a que
el programador encargado de implementar una funcionalidad específica no debería estar al
tanto de las otras dimensiones que pueden afectar su código. La cuantificación es la posibilidad
de indicar en qué puntos de unión se aplicará un aspecto, sin necesidad de enumerarlos uno
por uno.

Prescindencia y Cuantificación

La prescindencia se corresponde con el principio de abstracción y encapsulamiento
omnipresente en la ingeniería de software, es básica para poder mantener la separación de
incumbencias. Si se hiciera necesario que un programador tuviera en cuenta, al escribir su
código, cuáles serán los aspectos que se le aplicarán, no estaríamos logrando la separación de
incumbencias que planteamos como objetivo inicial. Por ejemplo, no podríamos cambiar a qué
puntos    de    unión     afectará  un     aspecto,     sin   modificar   el   código    base.

La cuantificación también es esencial al trabajar con aspectos. Recuerden que hablando de
incumbencias transversales dijimos que cada sistema tenía una política sobre dónde se
requería entrelazar un servicio. Como los aspectos pretenden modularizar las incumbencias
transversales, la política debe hacerse explícita y formar parte del aspecto. En la notación que
vimos, la cuantificación está dada por el lenguaje de definición de pointcuts y, en particular, por
los comodines (*, +, ..), que permiten referirse de forma genérica un grupo de puntos de unión.
Es el equivalente a definir un conjunto por comprensión, diciendo qué propiedad cumplen todos
sus      miembros,        en    lugar      de     hacerlo      por     extensión,     listándolos.

En algunas supuestas implementaciones de AOP, se requiere que el programador del código
base indique de alguna forma en su programa, en cada punto de unión, qué aspectos deben
insertarse en ese lugar. Este mecanismo viola tanto la prescindencia como la cuantificación,
porque el programador no puede ignorar los aspectos y debe enumerar los puntos de unión.

Otras implementaciones brindan herramientas para que, por fuera del código, se señale en
forma interactiva dónde se espera que se entrelace un aspecto. Este método es más 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 violación del
principio de cuantificación: la política no se hace explícita ni se modulariza como parte de los
aspectos, está dada por las acciones del encargado de marcar a mano los puntos de unión.
Incluso si el resultado de esas acciones se almacena en algún formato, los puntos de unión
aparecen listados y no definidos por sus propiedades.

Aspectos y .NET

El desarrollo de software orientado a aspectos todavía se encuentra en un estado incipiente. La
mayoría de las implementaciones es de carácter experimental. La tecnología no ha sido hasta
ahora claramente adoptada por la industria, aunque importantes empresas relacionadas con el
desarrollo    de     software    están   financiando    proyectos   ambiciosos     de    AOP.

Una de las razones para la falta de adopción puede encontrarse en la dificultad que introducen
los aspectos para razonar sobre los programas. Muchas de las técnicas de diseño y de las
buenas prácticas de codificación actuales tienen por objetivo garantizar la composicionalidad
del razonamiento sobre programas: no hace falta leer el código entero para entender qué es lo
que hace un fragmento, se pueden extraes conclusiones sobre el comportamiento local y esas
conclusiones siguen siendo válidas sin importar cómo se inserte el fragmento en un sistema
mayor. Pero los aspectos pueden invalidar esta premisa, ya que permiten modificar quot;desde
afueraquot;      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 específico
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             dirección.

Otro inconveniente que atenta contra la adopción generalizada de AOP es la reusabilidad
reducida. El principio de prescindencia garantiza el desacoplamiento en un solo sentido: el
código base no depende de los aspectos. Pero las notaciones de cuantificación y acceso al
contexto como las que vimos atan los aspectos a una aplicación en particular u obligan al
programador a seguir convenciones de codificación, lo cual va en contra de la prescindencia.
Esto se debe al uso de comodines basados en el nombre que tienen los identificadores del
código                                                                                base.

Siguiendo el ejemplo de la Figura 3, los programadores estarían obligados a poner nombres
que comenzaran con set a todos los métodos cuya tarea fuera la de cambiar el valor de una
propiedad que alterara la presentación en pantalla. O, alternativamente, haría falta modificar la
definición del pointcut para adaptarla a otra convención (por ejemplo, si en una aplicación el
nombre de estos métodos comenzara con update). Evitar estos problemas es el objetivo de
nuestro proyecto SetPoint (4) que incluye un desarrollo sobre la plataforma Microsoft .NET.

Además 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 tecnología 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 técnicas de entretejido dinámico; las variantes
estáticas son altamente dependientes del lenguaje, porque implican preprocesar o compilar el
código base. Esto complica un poco la implementación, porque el entretejido dinámico implica,
la mayoría de las veces, modificar la máquina virtual o el soporte de tiempo de ejecución de los
lenguajes (en este caso, el CLR). Tal vez por eso, como podrán observar en la página de
proyectos investigación 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 aplicación de las ideas de AOP al desarrollo de software la
ofrecen algunas características de ASP.NET. En particular, el mecanismo de validación de
formularios y el de autenticación. En ambos casos, podemos hablar de separación de
incumbencia e incluso de cierto grado de prescindencia, ya que el programador de la
funcionalidad básica no debe preocuparse por implementar estas incumbencias. La validación
de los valores ingresados por el usuario en una página 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 validación mismo. La autenticación de usuarios para todas las páginas de una
aplicación tampoco se hace página por página, sino a través de un archivo de configuración.
En    ambos      casos,   el    entrelazado    está   a    cargo     del   framework    .NET.

Las características 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. Además, aunque comparten
con los aspectos la ventaja de la prescindencia, no ofrecen la de la cuantificación. Los
controles de validación requieren indicar explícitamente el campo que deben verificar. La
autenticación brinda una forma de cuantificación universal: afecta, en principio, a todas las
páginas de una aplicación; pero si se pretende acotar su alcance, se debe caer nuevamente en
la enumeración. A pesar de no tratarse de aspectos en todo su esplendor, sirven como
ejemplos del trabajo que pueden ahorrar estas técnicas en el proceso de desarrollo.

También podrían 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 cuantificación, siempre hay que
indicar caso por caso a qué componentes afectan.




      E.    W.    Dijkstra,   A   Discipline    of   Programming.      Prentice    Hall,   1976.
(1)
(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
                                                  http://www.dc.uba.ar/people/proyinv/setpoint
(5)
                                                        http://aosd.net/technology/research.php
(4)




                Nicolás Kicillof es Profesor Adjunto del Departamento de Computación de la
                Facultad de Ciencias Exactas y Naturales de la Universidad de Buenos Aires,
                donde dicta la materia Paradigmas de Lenguajes de Programación. Sus
                campos de investigación son la Ingeniería de Software y los lenguajes de
                programación. Tiene una vasta experiencia profesional liderando equipos de
                consultoría y desarrollo, especialmente en plataformas Microsoft.

Más contenido relacionado

La actualidad más candente

M O D U L A R I D A D
M O D U L A R I D A DM O D U L A R I D A D
M O D U L A R I D A DJORGE ARMANDO
 
Modularidad en Jav
Modularidad en JavModularidad en Jav
Modularidad en Javmaynet
 
Del análisis al diseño. conclusión de la fase del análisis. diagramas de cola...
Del análisis al diseño. conclusión de la fase del análisis. diagramas de cola...Del análisis al diseño. conclusión de la fase del análisis. diagramas de cola...
Del análisis al diseño. conclusión de la fase del análisis. diagramas de cola...Juan Pablo Bustos Thames
 
Paradigmas de programacion
Paradigmas de programacionParadigmas de programacion
Paradigmas de programacionSalvadorJimnez10
 
KTN05-MODELOS EN LA DINÁMICA DE SISTEMAS Y EL PROCESO DE CONSTRUCCIÓN
KTN05-MODELOS EN LA DINÁMICA DE SISTEMAS Y EL PROCESO DE CONSTRUCCIÓNKTN05-MODELOS EN LA DINÁMICA DE SISTEMAS Y EL PROCESO DE CONSTRUCCIÓN
KTN05-MODELOS EN LA DINÁMICA DE SISTEMAS Y EL PROCESO DE CONSTRUCCIÓNKOTENA BCS
 
Programacion Estructurada
Programacion EstructuradaProgramacion Estructurada
Programacion EstructuradaClaretiano
 
Programacion modular
Programacion modularProgramacion modular
Programacion modularCarmen Silva
 
Programación modular. Esteban Alzate Duque
Programación modular. Esteban Alzate DuqueProgramación modular. Esteban Alzate Duque
Programación modular. Esteban Alzate DuqueEsteban Duque
 
Programación modular en Introducción a la Programación
Programación modular en Introducción a la ProgramaciónProgramación modular en Introducción a la Programación
Programación modular en Introducción a la ProgramaciónFacultad de Ciencias y Sistemas
 
Conceptos Basicos Uml
Conceptos Basicos UmlConceptos Basicos Uml
Conceptos Basicos Umlfelix17
 

La actualidad más candente (20)

1.2 modularidad
1.2 modularidad1.2 modularidad
1.2 modularidad
 
M O D U L A R I D A D
M O D U L A R I D A DM O D U L A R I D A D
M O D U L A R I D A D
 
Programacion MODULAR
Programacion MODULARProgramacion MODULAR
Programacion MODULAR
 
Patrones GRASP
Patrones GRASPPatrones GRASP
Patrones GRASP
 
Programación modular
Programación modularProgramación modular
Programación modular
 
Programación modular
Programación modularProgramación modular
Programación modular
 
Modularidad en Jav
Modularidad en JavModularidad en Jav
Modularidad en Jav
 
Del análisis al diseño. conclusión de la fase del análisis. diagramas de cola...
Del análisis al diseño. conclusión de la fase del análisis. diagramas de cola...Del análisis al diseño. conclusión de la fase del análisis. diagramas de cola...
Del análisis al diseño. conclusión de la fase del análisis. diagramas de cola...
 
Paradigmas de programacion
Paradigmas de programacionParadigmas de programacion
Paradigmas de programacion
 
KTN05-MODELOS EN LA DINÁMICA DE SISTEMAS Y EL PROCESO DE CONSTRUCCIÓN
KTN05-MODELOS EN LA DINÁMICA DE SISTEMAS Y EL PROCESO DE CONSTRUCCIÓNKTN05-MODELOS EN LA DINÁMICA DE SISTEMAS Y EL PROCESO DE CONSTRUCCIÓN
KTN05-MODELOS EN LA DINÁMICA DE SISTEMAS Y EL PROCESO DE CONSTRUCCIÓN
 
Programacion Estructurada
Programacion EstructuradaProgramacion Estructurada
Programacion Estructurada
 
M o d_u_l_a_r_i_d_a_d
M o d_u_l_a_r_i_d_a_dM o d_u_l_a_r_i_d_a_d
M o d_u_l_a_r_i_d_a_d
 
Programacion modular
Programacion modularProgramacion modular
Programacion modular
 
Programación modular. Esteban Alzate Duque
Programación modular. Esteban Alzate DuqueProgramación modular. Esteban Alzate Duque
Programación modular. Esteban Alzate Duque
 
Paradigmas
ParadigmasParadigmas
Paradigmas
 
Introducción a UML
Introducción a UMLIntroducción a UML
Introducción a UML
 
Programacion estructurada
Programacion estructuradaProgramacion estructurada
Programacion estructurada
 
Programación modular en Introducción a la Programación
Programación modular en Introducción a la ProgramaciónProgramación modular en Introducción a la Programación
Programación modular en Introducción a la Programación
 
IntroduccióN Uml
IntroduccióN UmlIntroduccióN Uml
IntroduccióN Uml
 
Conceptos Basicos Uml
Conceptos Basicos UmlConceptos Basicos Uml
Conceptos Basicos Uml
 

Destacado

Sin Sho Temple, Sansia, Taipei
Sin Sho Temple, Sansia, TaipeiSin Sho Temple, Sansia, Taipei
Sin Sho Temple, Sansia, TaipeiIvy Cheng
 
Aso’S Sweets
Aso’S SweetsAso’S Sweets
Aso’S Sweetsmuha
 
Area Audiovisual
Area AudiovisualArea Audiovisual
Area AudiovisualCati Mier
 
Festa De Natal Eb1nº2 De Loulé
Festa De Natal   Eb1nº2 De LouléFesta De Natal   Eb1nº2 De Loulé
Festa De Natal Eb1nº2 De Louléisigoncalves
 

Destacado (8)

Sin Sho Temple, Sansia, Taipei
Sin Sho Temple, Sansia, TaipeiSin Sho Temple, Sansia, Taipei
Sin Sho Temple, Sansia, Taipei
 
Informatik
InformatikInformatik
Informatik
 
Aso’S Sweets
Aso’S SweetsAso’S Sweets
Aso’S Sweets
 
Area Audiovisual
Area AudiovisualArea Audiovisual
Area Audiovisual
 
Network 2
Network 2Network 2
Network 2
 
Dl06
Dl06Dl06
Dl06
 
Festa De Natal Eb1nº2 De Loulé
Festa De Natal   Eb1nº2 De LouléFesta De Natal   Eb1nº2 De Loulé
Festa De Natal Eb1nº2 De Loulé
 
ApresentaçãO1
ApresentaçãO1ApresentaçãO1
ApresentaçãO1
 

Similar a Programación orientada a aspectos (AOP

Desarrollo de Software Orientado a Aspectos
Desarrollo de Software Orientado a AspectosDesarrollo de Software Orientado a Aspectos
Desarrollo de Software Orientado a Aspectosmartinp
 
Glosario de terminos
Glosario de terminosGlosario de terminos
Glosario de terminosJose Risso
 
Fundamentos de Diseño Orientado a Objetos
Fundamentos de Diseño Orientado a ObjetosFundamentos de Diseño Orientado a Objetos
Fundamentos de Diseño Orientado a Objetosforwer1223
 
MODULO II ALGORITMO Y PROGRAMACIÓN ESTRUCTURA DE PROGRAMA.pdf
MODULO II ALGORITMO Y PROGRAMACIÓN ESTRUCTURA DE PROGRAMA.pdfMODULO II ALGORITMO Y PROGRAMACIÓN ESTRUCTURA DE PROGRAMA.pdf
MODULO II ALGORITMO Y PROGRAMACIÓN ESTRUCTURA DE PROGRAMA.pdfannalybautistaruiz
 
MODULO II ALGORITMO Y PROGRAMACIÓN ESTRUCTURA DE PROGRAMA.pdf
MODULO II ALGORITMO Y PROGRAMACIÓN ESTRUCTURA DE PROGRAMA.pdfMODULO II ALGORITMO Y PROGRAMACIÓN ESTRUCTURA DE PROGRAMA.pdf
MODULO II ALGORITMO Y PROGRAMACIÓN ESTRUCTURA DE PROGRAMA.pdfannalybautistaruiz
 
Diseño estructurado
Diseño estructuradoDiseño estructurado
Diseño estructuradoDascorp
 
Clase no. 1 unidad no. iii introduccion al analisis y diseño estructurado d...
Clase no. 1 unidad no. iii  introduccion al analisis y diseño estructurado  d...Clase no. 1 unidad no. iii  introduccion al analisis y diseño estructurado  d...
Clase no. 1 unidad no. iii introduccion al analisis y diseño estructurado d...negroues
 
Uso de-patrones-de-arquitectura-capitulo-4
Uso de-patrones-de-arquitectura-capitulo-4Uso de-patrones-de-arquitectura-capitulo-4
Uso de-patrones-de-arquitectura-capitulo-4Ozzy Bull
 
Introducción A La Orientación A Aspectos - Programador PHP
Introducción A La Orientación A Aspectos - Programador PHPIntroducción A La Orientación A Aspectos - Programador PHP
Introducción A La Orientación A Aspectos - Programador PHPJuan Belón Pérez
 
Aspect Oriented Programming introduction
Aspect Oriented Programming introductionAspect Oriented Programming introduction
Aspect Oriented Programming introductionMiguel Pastor
 
Español estructurado
Español estructuradoEspañol estructurado
Español estructuradoJorge Garcia
 
Apun9algol
Apun9algolApun9algol
Apun9algolpabesacv
 
Tema 2.UML parte 1.ppt
Tema 2.UML parte 1.pptTema 2.UML parte 1.ppt
Tema 2.UML parte 1.pptRafaelAcedo2
 
El algoritmo como estrategia y herramienta para la solución de problemas
El algoritmo como estrategia y herramienta para la solución de problemasEl algoritmo como estrategia y herramienta para la solución de problemas
El algoritmo como estrategia y herramienta para la solución de problemasBERNARDAURELIOFELIZM
 

Similar a Programación orientada a aspectos (AOP (20)

Desarrollo de Software Orientado a Aspectos
Desarrollo de Software Orientado a AspectosDesarrollo de Software Orientado a Aspectos
Desarrollo de Software Orientado a Aspectos
 
Clase 29
Clase 29Clase 29
Clase 29
 
Top down
Top downTop down
Top down
 
Conceptos de diseño
Conceptos de diseñoConceptos de diseño
Conceptos de diseño
 
Glosario de terminos
Glosario de terminosGlosario de terminos
Glosario de terminos
 
Presentación1.pptx
Presentación1.pptxPresentación1.pptx
Presentación1.pptx
 
Fundamentos de Diseño Orientado a Objetos
Fundamentos de Diseño Orientado a ObjetosFundamentos de Diseño Orientado a Objetos
Fundamentos de Diseño Orientado a Objetos
 
MODULO II ALGORITMO Y PROGRAMACIÓN ESTRUCTURA DE PROGRAMA.pdf
MODULO II ALGORITMO Y PROGRAMACIÓN ESTRUCTURA DE PROGRAMA.pdfMODULO II ALGORITMO Y PROGRAMACIÓN ESTRUCTURA DE PROGRAMA.pdf
MODULO II ALGORITMO Y PROGRAMACIÓN ESTRUCTURA DE PROGRAMA.pdf
 
MODULO II ALGORITMO Y PROGRAMACIÓN ESTRUCTURA DE PROGRAMA.pdf
MODULO II ALGORITMO Y PROGRAMACIÓN ESTRUCTURA DE PROGRAMA.pdfMODULO II ALGORITMO Y PROGRAMACIÓN ESTRUCTURA DE PROGRAMA.pdf
MODULO II ALGORITMO Y PROGRAMACIÓN ESTRUCTURA DE PROGRAMA.pdf
 
Laboratorio iii
Laboratorio iiiLaboratorio iii
Laboratorio iii
 
Diseño estructurado
Diseño estructuradoDiseño estructurado
Diseño estructurado
 
Clase no. 1 unidad no. iii introduccion al analisis y diseño estructurado d...
Clase no. 1 unidad no. iii  introduccion al analisis y diseño estructurado  d...Clase no. 1 unidad no. iii  introduccion al analisis y diseño estructurado  d...
Clase no. 1 unidad no. iii introduccion al analisis y diseño estructurado d...
 
Uso de-patrones-de-arquitectura-capitulo-4
Uso de-patrones-de-arquitectura-capitulo-4Uso de-patrones-de-arquitectura-capitulo-4
Uso de-patrones-de-arquitectura-capitulo-4
 
Tarea 13
Tarea 13Tarea 13
Tarea 13
 
Introducción A La Orientación A Aspectos - Programador PHP
Introducción A La Orientación A Aspectos - Programador PHPIntroducción A La Orientación A Aspectos - Programador PHP
Introducción A La Orientación A Aspectos - Programador PHP
 
Aspect Oriented Programming introduction
Aspect Oriented Programming introductionAspect Oriented Programming introduction
Aspect Oriented Programming introduction
 
Español estructurado
Español estructuradoEspañol estructurado
Español estructurado
 
Apun9algol
Apun9algolApun9algol
Apun9algol
 
Tema 2.UML parte 1.ppt
Tema 2.UML parte 1.pptTema 2.UML parte 1.ppt
Tema 2.UML parte 1.ppt
 
El algoritmo como estrategia y herramienta para la solución de problemas
El algoritmo como estrategia y herramienta para la solución de problemasEl algoritmo como estrategia y herramienta para la solución de problemas
El algoritmo como estrategia y herramienta para la solución de problemas
 

Programación orientada a aspectos (AOP

  • 1. Programación Orientada a Aspectos (AOP) Por Nicolás Kicillof Introducción Los conceptos y tecnologías reunidos bajo el nombre quot;programación orientada a aspectosquot; (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 separación de incumbencias (separation of concerns). AOP no es el único intento por solucionar este problema, del que voy a hablar a continuación: hay varias propuestas, muchas de las cuales se agrupan (junto con AOP) en el campo de estudio denominado ASoC (Advanced Separation of Concerns). Separación de Incumbencias El principio de separación de incumbencias fue identificado en la década 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 función específica que debe realizar una aplicación, pero también surgen otras como por ejemplo distribución, persistencia, replicación, sincronización, 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 separación de actividades de ingeniería en el tiempo y por su objetivo. Definir subsistemas, objetos y componentes son otras formas de poner en práctica el principio de separación de incumbencias. Por eso podemos decir que se trata de un principio rector omnipresente en el proceso de desarrollo de software. Las técnicas de modelado que se usan en la etapa de diseño 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 técnicas sufren en su mayoría la llamada quot;tiranía de la descomposición dominantequot; que consiste en guiarse al modelar, implícita o explícitamente, por una visión jerárquica determinada de la organización 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 descomposición, como veremos más adelante. Las construcciones provistas por los lenguajes de programación, que fueron creados para implementar los modelos generados por las técnicas de diseño existentes, reproducen las jerarquías y, por lo tanto, comparten el defecto explicado en el párrafo anterior. En el paradigma de programación imperativa, la descomposición consiste en identificar procedimientos que resuelvan parte del problema, y la jerarquía se da en el árbol de ejecución, según el cual los procedimientos se invocan unos a otros. En el caso de la programación orientada a objetos, la jerarquía generada en la etapa de diseño suele plasmarse en las relaciones de herencia o de composición entre objetos. Por ejemplo, algunos patrones de diseño de uso habitual como observador (observer), visitante (visitor) y mediador (mediator) (2) exhiben estos problemas, ya que para aplicarlos es necesario adaptar a ellos más de una clase. El problema aparece cuando una incumbencia afecta a distintas partes del sistema que no aparecen relacionadas en la jerarquía. En ese caso, la única solución suele ser escribir código repetido que resuelva esa incumbencia para cada subsistema. Un ejemplo clásico de la programación orientada a aspectos es el de distintos métodos de un
  • 2. sistema de edición de gráficos que, luego de modificar la representación 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 código atravesando partes del sistema no relacionadas en el modelo, se denominan incumbencias transversales (crosscutting concerns). Incumbencias Transversales Otro ejemplo, también clásico, de incumbencias transversales es el logging o registro de la actividad de una aplicación. En varios puntos de ejecución, que podrían pertenecer a elementos del programa disconexos, queremos invocar un método 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 código disperso y enredado (scattering and tangling). Se habla de código 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 módulo del sistema, las líneas de código que invocan el servicio de logging están en rojo.
  • 3. Logging Figura 2: en Apache Tomcat [Kiczales 2001] Si una misma operación tiene que acceder a varios servicios (logging, locking, presentación, transporte, autenticación, seguridad, etc), además de cumplir con su función específica, estamos ante una muestra de código enredado. La fuente de estos problemas es que en realidad cada aplicación tiene una política sobre dónde se requiere cada uno de estos servicios; pero esa política no es explícita, está oculta como parte de la estructura del programa. Esto hace que sea difícil de entender, razonar sobre ella y mantenerla. La solución que propone la comunidad de AOP es modularizar las incumbencias transversales, justamente esa es la definición de aspecto: una incumbencia transversal modularizada. Aspectos Ya sabemos cuál es la idea detrás de un aspecto, veamos ahora cómo se llevan a la práctica. Empecemos por ver la propuesta de AOP para resolver la dispersión 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 instrucción Display.update(); al terminar la invocación a cualquier método cuyo nombre comienze con set, de una subclase de La notación usada está basada en AspectJ FigureElement. (3). Para entender cómo se aplica un aspecto, tenemos que empezar por el concepto de punto de unión (join point). Los puntos de unión son puntos en la ejecución de un programa. Por ejemplo, quot;al invocar al método Line.getP1() por cuarta vezquot;. Es importante recalcar que los puntos de unión no son posiciones en el código fuente (ni dentro de una instrucción, ni entre instrucciones), sino en la ejecución del programa. La frase anterior habla de la cuarta invocación de un método en una ejecución, y esto no corresponde a un punto en el código. En distintas ejecuciones podría variar qué instrucción es la que invoca por cuarta vez a Line.getP1(), por ejemplo, se podría llamar a este método 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 ejecución, la cuarta llamada a este método podría ser en esta instrucción o en otra.
  • 4. Figura 3: Aspecto de actualización de pantalla Ahora pasemos a hablar de un concepto un poco más complicado que el de punto de unión, que es el de pointcut. Un pointcut es un predicado, una afirmación que es cumplida por un conjunto de puntos de unión. En nuestro ejemplo de la Figura 3, aparece un pointcut: que vamos a analizar por partes. call(void FigureElement+.set*(..)) significa quot;al invocar (call) cualquier método 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 parámetros (..)quot;. El siguiente fragmento es fácil de comprender: call(void FigureElement.moveBy(int, int)). El operador de disyunción (||) se usa para unir estos dos pointcuts y formar uno nuevo. Los puntos de unión que cumplan el pointcut compuesto serán aquellos que cumplan uno u otro de los dos. Además 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 también formas de acceder al contexto como target (clase que recibe el mensaje), (argumentos de una llamada), etc. args Los pointcuts son parte de un aspecto, indican dónde (en qué puntos de unión) 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 unión. En la Figura 3, el consejo dice que hay que agregar la instrucción Display.Update(); después (after) de cada uno de los puntos de unión indicados por el pointcut. En vez de after, se podría haber puesto before (antes), after returning (después de ejecutar un método en forma normal), after throwing (después de arrojar una excepción) o (en lugar de ejecutar el punto de unión). around El mecanismo por el cual se combinan los aspectos con el código 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 precompilación: se toma el código base y los aspectos, y se produce nuevo código fuente con el resultado del entretejido, insertando los consejos en los puntos de unión correspondiente. También se puede hacer durante la compilación, generando código objeto que cumpla la funcionalidad base más la de los aspectos. Y otra alternativa es el llamado entretejido dinámico, por el cual se controla la ejecución del programa y, cada vez que se llega a un punto de unión incluido en un pointcut de un aspecto, se ejecuta el consejo asociado.
  • 5. En este ejemplo tan sencillo que vimos, aparecen ya las dos ideas más poderosas que hay detrás de los aspectos: prescindencia (obliviousness) y cuantificación (quantification). Ambas están asociadas al mecanismo de construcción de pointcuts. La prescindencia se refiere a que el programador encargado de implementar una funcionalidad específica no debería estar al tanto de las otras dimensiones que pueden afectar su código. La cuantificación es la posibilidad de indicar en qué puntos de unión se aplicará un aspecto, sin necesidad de enumerarlos uno por uno. Prescindencia y Cuantificación La prescindencia se corresponde con el principio de abstracción y encapsulamiento omnipresente en la ingeniería de software, es básica para poder mantener la separación de incumbencias. Si se hiciera necesario que un programador tuviera en cuenta, al escribir su código, cuáles serán los aspectos que se le aplicarán, no estaríamos logrando la separación de incumbencias que planteamos como objetivo inicial. Por ejemplo, no podríamos cambiar a qué puntos de unión afectará un aspecto, sin modificar el código base. La cuantificación también es esencial al trabajar con aspectos. Recuerden que hablando de incumbencias transversales dijimos que cada sistema tenía una política sobre dónde se requería entrelazar un servicio. Como los aspectos pretenden modularizar las incumbencias transversales, la política debe hacerse explícita y formar parte del aspecto. En la notación que vimos, la cuantificación está dada por el lenguaje de definición de pointcuts y, en particular, por los comodines (*, +, ..), que permiten referirse de forma genérica un grupo de puntos de unión. Es el equivalente a definir un conjunto por comprensión, diciendo qué propiedad cumplen todos sus miembros, en lugar de hacerlo por extensión, listándolos. En algunas supuestas implementaciones de AOP, se requiere que el programador del código base indique de alguna forma en su programa, en cada punto de unión, qué aspectos deben insertarse en ese lugar. Este mecanismo viola tanto la prescindencia como la cuantificación, porque el programador no puede ignorar los aspectos y debe enumerar los puntos de unión. Otras implementaciones brindan herramientas para que, por fuera del código, se señale en forma interactiva dónde se espera que se entrelace un aspecto. Este método es más 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 violación del principio de cuantificación: la política no se hace explícita ni se modulariza como parte de los aspectos, está dada por las acciones del encargado de marcar a mano los puntos de unión. Incluso si el resultado de esas acciones se almacena en algún formato, los puntos de unión aparecen listados y no definidos por sus propiedades. Aspectos y .NET El desarrollo de software orientado a aspectos todavía se encuentra en un estado incipiente. La mayoría de las implementaciones es de carácter experimental. La tecnología no ha sido hasta ahora claramente adoptada por la industria, aunque importantes empresas relacionadas con el desarrollo de software están financiando proyectos ambiciosos de AOP. Una de las razones para la falta de adopción puede encontrarse en la dificultad que introducen los aspectos para razonar sobre los programas. Muchas de las técnicas de diseño y de las buenas prácticas de codificación actuales tienen por objetivo garantizar la composicionalidad del razonamiento sobre programas: no hace falta leer el código entero para entender qué es lo que hace un fragmento, se pueden extraes conclusiones sobre el comportamiento local y esas conclusiones siguen siendo válidas sin importar cómo se inserte el fragmento en un sistema mayor. Pero los aspectos pueden invalidar esta premisa, ya que permiten modificar quot;desde afueraquot; 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 específico 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
  • 6. comunidad de AOSD en esa dirección. Otro inconveniente que atenta contra la adopción generalizada de AOP es la reusabilidad reducida. El principio de prescindencia garantiza el desacoplamiento en un solo sentido: el código base no depende de los aspectos. Pero las notaciones de cuantificación y acceso al contexto como las que vimos atan los aspectos a una aplicación en particular u obligan al programador a seguir convenciones de codificación, lo cual va en contra de la prescindencia. Esto se debe al uso de comodines basados en el nombre que tienen los identificadores del código base. Siguiendo el ejemplo de la Figura 3, los programadores estarían obligados a poner nombres que comenzaran con set a todos los métodos cuya tarea fuera la de cambiar el valor de una propiedad que alterara la presentación en pantalla. O, alternativamente, haría falta modificar la definición del pointcut para adaptarla a otra convención (por ejemplo, si en una aplicación el nombre de estos métodos comenzara con update). Evitar estos problemas es el objetivo de nuestro proyecto SetPoint (4) que incluye un desarrollo sobre la plataforma Microsoft .NET. Además 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 tecnología 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 técnicas de entretejido dinámico; las variantes estáticas son altamente dependientes del lenguaje, porque implican preprocesar o compilar el código base. Esto complica un poco la implementación, porque el entretejido dinámico implica, la mayoría de las veces, modificar la máquina virtual o el soporte de tiempo de ejecución de los lenguajes (en este caso, el CLR). Tal vez por eso, como podrán observar en la página de proyectos investigación 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 aplicación de las ideas de AOP al desarrollo de software la ofrecen algunas características de ASP.NET. En particular, el mecanismo de validación de formularios y el de autenticación. En ambos casos, podemos hablar de separación de incumbencia e incluso de cierto grado de prescindencia, ya que el programador de la funcionalidad básica no debe preocuparse por implementar estas incumbencias. La validación de los valores ingresados por el usuario en una página 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 validación mismo. La autenticación de usuarios para todas las páginas de una aplicación tampoco se hace página por página, sino a través de un archivo de configuración. En ambos casos, el entrelazado está a cargo del framework .NET. Las características 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. Además, aunque comparten con los aspectos la ventaja de la prescindencia, no ofrecen la de la cuantificación. Los controles de validación requieren indicar explícitamente el campo que deben verificar. La autenticación brinda una forma de cuantificación universal: afecta, en principio, a todas las páginas de una aplicación; pero si se pretende acotar su alcance, se debe caer nuevamente en la enumeración. A pesar de no tratarse de aspectos en todo su esplendor, sirven como ejemplos del trabajo que pueden ahorrar estas técnicas en el proceso de desarrollo. También podrían 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 cuantificación, siempre hay que indicar caso por caso a qué componentes afectan. E. W. Dijkstra, A Discipline of Programming. Prentice Hall, 1976. (1)
  • 7. (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 http://www.dc.uba.ar/people/proyinv/setpoint (5) http://aosd.net/technology/research.php (4) Nicolás Kicillof es Profesor Adjunto del Departamento de Computación de la Facultad de Ciencias Exactas y Naturales de la Universidad de Buenos Aires, donde dicta la materia Paradigmas de Lenguajes de Programación. Sus campos de investigación son la Ingeniería de Software y los lenguajes de programación. Tiene una vasta experiencia profesional liderando equipos de consultoría y desarrollo, especialmente en plataformas Microsoft.