Programación Orientada por aspectos (AspectJ)

Anuncio
Programación Orientada por
Aspectos
Rubby Casallas
Grupo de Construcción de Software
Universidad de los Andes
1
Referencias
http://eclipse.org/aspectj/
http://www.theserverside.com/events/video
s/GregorKiczalesText/interview.jsp
http://www.onjava.com/pub/a/onjava/2004/
01/14/aop.html
http://www.onjava.com/pub/a/onjava/2004/
08/25/aoa.html
2
Agenda
Motivación
Conceptos Básicos
El lenguaje AspectJ:
Pointcuts
Advices
Aspects
Introductions
Ejemplos
3
Motivación
Ejemplo:
Se necesita saber cuanto tiempo se demora la
ejecución de algunos métodos de una aplicación
4
Motivación
public class BankAccount {
public void withdraw (double amount) {
long startTime = System.currentTimeMillis();
try {
// Actual method body... }
finally {
long endTime = System.currentTimeMillis() –
startTime;
System.out.println("withdraw took: " + endTime);
}
}
}
5
Motivación: Aspectos transversales
Código similar en cada clase y cada método
donde se quiera hacer la medición
Si se necesitara un cambio en ese código
tocaría cambiar en todas las clases donde
está
No se puede decir apagar o prender la
ejecución de ese código
6
Motivación: Aspectos transversales
Código similar en cada clase y cada método
donde se quiera hacer la medición
Si se necesitara un cambio en ese código
tocaría cambiar en todas las clases donde
está
No se puede decir apagar o prender la
ejecución de ese código
El anterior es un ejemplo de un aspecto transversal a la
aplicación.
Es transversal porque la misma lógica se debe escribir en
7
varias partes de la aplicación.
Motivación: variantes como aspectos
En el contexto de una línea de producto:
una variante opcional puede modelarse como un
aspecto
ver ejemplo en:
Are Aspects useful for Managing Variability in Software Product Lines? A Case Study
(2005). Alexander Nyßen , Shmuel Tyszberowicz , Thomas Weiler
In Aspects and Software Product Lines: An Early Aspects Workshop at SPLC 2005
DOWNLOAD: http://trese.cs.utwente.nl/workshops/early-aspects
8
Conceptos Básicos
Un aspecto es una preocupación común a
varias clases de una aplicación
El aspecto es “casi siempre” ortogonal a lo
que la clase representa
Por ejemplo:
Logger, requerimientos no funcionales, testing y
validación de contratos, etc.
9
Conceptos Básicos
Un aspecto es una unidad funcional que
permite expresar una estructura de código en
diferentes partes de un programa
Un aspecto está compuesto de dos partes:
el punto de corte (point cut) que indica en qué
partes del código se va a introducir un código
definido
el código del aspecto que típicamente se llama un
advice
10
Conceptos Básicos
Curso
0..*
T ema
0..*
Profesor
0.. *
0..*
Material
0..*
0..*
0..*
0..*
0..*
11
Conceptos Básicos
Problema:
Incluir instrucciones en todos los métodos de
todas las clases para hacer un logger!
Al comienzo de la ejecución de cada método:
logger.info("Entering: " + <nombremetodo>);
12
Conceptos Básicos
Curso
0..*
T ema
0..*
Profesor
0.. *
0..*
Material
0..*
0..*
0..*
0..*
0..*
13
Conceptos Básicos
Curso
0..*
Tema
aspecto logger Operador “entretejer”
(weaving) )
0..*
Profesor
0..*
0..*
Material
0..*
0..*
0..*
0..*
0..*
14
Ejemplo: AspectJ
aspect simpleLogger {
pointcut tracedCall():
call(public * *(..));
before(): tracedCall() {
logger.info("Entering: " + thisJoinPoint);
}
aspecto logger
}
15
Ejemplo: AspectJ
aspect simpleLogger {
pointcut tracedCall():
call(public * *(..));
before(): tracedCall() {
logger.info("Entering: " + thisJoinPoint);
}
}
Puntos de la ejecución del programa
16
Ejemplo: AspectJ
aspect simpleLogger {
pointcut tracedCall():
call(public * *(..));
before(): tracedCall() {
logger.info("Entering: " + thisJoinPoint);
}
}
La instrucción del logger se va a
ejecutar justo antes de alcanzar el punto
tracedCall
17
Agenda
Conceptos Básicos
El lenguaje AspectJ:
Join point
Pointcuts
Advices
Aspects
Introductions
Ejemplos
18
Lo básico
Un punto de unión (join point) es un punto
bien definido en el flujo de ejecución de un
programa.
method & constructor call
method & constructor execution
field get & set
exception handler execution
static & dynamic initialization
19
Lo básico
o1:C1
m() {
...
// llamando a m2
o2.m2(x,y,z);
....
}
o2:C2
punto de unión
(join point)
m2() {
...
//ejecutando m2
...
}
20
Lo básico
o1:C1
m() {
...
// llamando a m2
o2.m2(x,y,z);
....
}
punto de unión
(join point)
o2:C2
m2() {
...
//ejecutando m2
...
}
Al regresar del llamado también hay otro punto de unión
21
Lo básico
Constructores del lenguaje:
En un pointcut se define uno o más join points
de un programa
Un advice define el código que debe ser
ejecutado cuando en el flujo de ejecución del
programa se llegue a uno de los puntos definidos
en un pointcut
22
AspectJ: Pointcut
Puntos bien definidos en la ejecución del
programa.
Ejemplos:
call(void Point.setX(int))
Cualquier llamado al método setX de los objetos de
la clase Point
call(void Point.setX(int)) ||
call(void Point.setY(int))
Cualquier llamado al método setX OR setY de los
objetos de la clase Point
23
Pointcut
Se le puede dar un nombre a un pointcut.
Ejemplo:
pointcut move():
call(void FigureElement.setXY(int,int)) ||
call(void
call(void
call(void
call(void
Point.setX(int)) ||
Point.setY(int)) ||
Line.setP1(Point)) ||
Line.setP2(Point));
El pointcut move crosscut varias clases. (namebased crosscutting)
24
Pointcut
Más ejemplos:
pointcut setter():
target(Point) &&
(call(void setX(int)) || call(void
setY(int)));
25
Pointcut
Property-based crosscutting
Ejemplos:
call(void Figure.make*(..))
call(public * Figure.* (..))
26
Pointcut
Property-based crosscutting
Ejemplos:
cflow(move())
Identifica todos los puntos que ocurren entre
recibir llamados a métodos en move y retornar
de estos llamados (ya sea que se salió con
excepción o normalmente)
27
Pointcut
Pointcut más ejemplos:
pointcut ioHandler(): within(MyClass) &&
handler(IOException);
Identifica cada punto donde una excepción de tipo IOException es
manejada dentro del código definido en la clase MyClass
28
Agenda
Conceptos Básicos
El lenguaje AspectJ:
Pointcuts
Advices
Aspects
Introductions
Ejemplos
29
Advice
Un advice define código que debe ser
ejecutado en jointpoints.
Se puede indicar que el advice sea ejecutado
ANTES, DESPUES o en vez de un joint point.
Ejemplo:
after(): move() {
System.out.println("A figure element
moved.");
}
30
Advice
aspect A {
pointcut publicCall(): call(public Object *(..));
after() returning (Object o): publicCall() {
System.out.println("Returned normally with " +
o); }
after() throwing (Exception e): publicCall() {
System.out.println("Threw an exception: " + e);
}
after(): publicCall(){
System.out.println("Returned or threw an
Exception");
}
}
31
Pointcut y Advice
Contexto de ejecución de los pointcuts
Poincut básico:
call(void FigureElement.setXY(int, int))
32
Pointcut y Advice
En un advice se quiere poder hacer
referencia al objeto sobre el que se
llamó el método setXY y a los
argumentos con los que se invocó:
setXY(FigureElement fe, int x, int y):
call(void FigureElement.setXY(int, int))
&&
target(fe) &&
args(x, y);
33
Pointcut y Advice
... Y en el advice usamos el contexto:
after(FigureElement fe, int x,
int y): setXY(fe, x, y) {
System.out.println(fe + "
moved to (" + x + ", " + y +
").");
}
34
Advice: remplazar la ejecución
aspect A {
int around(): call(int C.foo()) {
return 3;
}
}
A retorna 3 en vez de lo que retornaba el método foo()
de las instancias de la clase C
35
Agenda
Conceptos Básicos
El lenguaje AspectJ:
Pointcuts
Advices
Aspects
Introductions
Ejemplos
36
Definición de Aspectos
Un aspecto es una unidad modular de una
implementación de un concern
aspect SimpleTracing {
pointcut tracedCall():
call(void FigureElement.draw(GraphicsContext));
before(): tracedCall() {
System.out.println("Entering: " + thisJoinPoint);
}
}
37
Definición de Aspectos
Un aspecto es una unidad modular de una
implementación de un concern
aspect SimpleTracing {
pointcut tracedCall():
call(void FigureElement.draw(GraphicsContext));
before(): tracedCall() {
System.out.println("Entering: " + thisJoinPoint);
}
}
El efecto del código es imprimir, antes de que se invoque el método draw
sobre cualquier objeto de la clase FigureElement, la línea:
Entering: call(void FigureElement.draw(GraphicsContext))
38
Definición de Aspectos
Se define de manera similar como una clase
y puede tener métodos, atributos,
inicializadores.
La implementación del concern se da en
términos de pointcuts, advice e introductions.
39
Definición de Aspectos
Por defecto, un aspecto es un singleton
Sólo hay una instancia del aspecto.
Los atributos son similares a los atributos
estáticos de una clase.
40
Definición de Aspectos: Ejemplos
aspect SetsInRotateCounting {
int rotateCount = 0;
int setCount = 0;
before(): call(void Line.rotate(double)) {
rotateCount++;
}
before(): call(void Point.set*(int)) &&
cflow(call(void Line.rotate(double))) {
setCount++;
}
}
41
Definición de Aspectos: Ejemplos
aspect SetsInRotateCounting {
int rotateCount = 0;
int setCount = 0;
before(): call(void Line.rotate(double)) {
rotateCount++;
}
before(): call(void Point.set*(int)) &&
cflow(call(void Line.rotate(double))) {
setCount++;
}
Cuántas
} veces fue invocado el método rotate de los objetos de la clase Line?
Cuántas veces los métodos que comienzan con set de los objetos de la clase Point,
Fueron llamados durante la ejecución de los métodos rotate de los objetos de la clase
Line?
42
Definición de Aspectos: Ejemplos
aspect PointBoundsChecking {
pointcut setX(int x): (call(void FigureElement.setXY(int, int))
&& args(x, *)) ||
(call(void Point.setX(int)) && args(x));
pointcut setY(int y): (call(void FigureElement.setXY(int, int))
&& args(*, y)) ||
(call(void Point.setY(int)) && args(y));
before(int x): setX(x) {
if ( x < MIN_X || x > MAX_X )
throw new IllegalArgumentException("x is out of bounds.");
}
before(int y): setY(y) {
if ( y < MIN_Y || y > MAX_Y )
throw new IllegalArgumentException("y is out of bounds.");
}
}
43
Definición de Aspectos: Ejemplos
static aspect RegistrationProtection {
pointcut register(): call(void Registry.register(FigureElement));
pointcut canRegister():
withincode(static * FigureElement.make*(..));
before(): register() && !canRegister() {
throw new IllegalAccessException("Illegal call " +
thisJoinPoint);
}
}
44
Agenda
Conceptos Básicos
El lenguaje AspectJ:
Pointcuts
Advices
Aspects
Introductions
Ejemplos
45
Introductions
Las Introductions en AspectJ son la
manera de modificar las clases y su
jerarquía
Permite adicionar nuevos métodos y
nuevas clases alterando la relación de
herencia entre las clases
Los Advice operan dinámicamente
Las Introductions operan estáticamente
46
Agenda
Conceptos Básicos
El lenguaje AspectJ:
Pointcuts
Advices
Aspects
Introductions
Ejemplos
47
Ejemplos
Tomados de:
http://www.eclipse.org/aspectj/doc/released/pr
ogguide/starting-development.html
Tracing
Profiling and Logging
Pre- and Post-Conditions
Contract Enforcement
48
Tracing
Objetivo: imprimir un mensaje cada vez que
se llama el método draw de un objeto de la
clase FigureElement
49
aspect SimpleTracing {
pointcut tracedCall():
call(void FigureElement.draw(..));
before(): tracedCall() {
System.out.println("Entering: " +
thisJoinPoint);
}
}
50
...
public static void main(String[] args) {
Point p1 = new Point();
Point p2 = new Point();
Line line = new Line(p1, p2);
line.draw();
}
Entering: call(void FigureElement.draw(Point, Point))
51
Profiling and Logging
Objetivo: contestar las siguientes
preguntas:
Cuántas veces el método rotate es llamado
sobre objetos de la clase Line?
Cuántas veces los métodos de la clase Point
que comienzan por set son llamados dentro de
la ejecución de rotate?
52
aspect SetsInRotateCounting {
int rotateCount = 0;
int setCount = 0;
before(): call(void Line.rotate(double)) {
rotateCount++;
}
before(): call(void Point.set*(int)) &&
cflow(call(void Line.rotate(double))) {
setCount++;
}
}
53
Pre- and Post-Conditions
aspect PointBoundsChecking {
pointcut setX(int x): call(void FigureElement.setXY(int, int)) && args(x, *))
|| (call(void Point.setX(int)) && args(x));
pointcut setY(int y): (call(void FigureElement.setXY(int, int)) && args(*, y))
|| (call(void Point.setY(int)) && args(y));
before(int x): setX(x) {
if ( x < MIN_X || x > MAX_X )
throw new IllegalArgumentException("x is out of bounds.");
}
before(int y): setY(y) {
if ( y < MIN_Y || y > MAX_Y )
throw new IllegalArgumentException("y is out of bounds.");
}
}
54
55
56
El compilador y el tejedor de AspectJ
1
2
3
Guide for the Developers of AspectJ's Compiler and Weaver, by Jim Hugunin
http://aspectprogrammer.org/modules/sections/index.php?op=viewarticle&artid=11
[Ultima visita 6-oct-2005]
57
Descargar