programmation par aspects

54
Programmation par aspects

Upload: shae

Post on 21-Jan-2016

22 views

Category:

Documents


0 download

DESCRIPTION

Programmation par aspects. XML parsing dans Tomcat. Construction du journal dans Tomcat. Le rouge montre les lignes de code qui traitent du logging Très mal modularisé. Le code traite de plusieurs aspects. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Programmation par aspects

Programmation par aspects

Page 2: Programmation par aspects

XML parsing dans Tomcat

Page 3: Programmation par aspects

Construction du journal dans Tomcat

Le rouge montre les lignes de code qui traitent du logging Très mal modularisé

Page 4: Programmation par aspects

Le code traite de plusieurs aspects

class Fraction { int numerator; int denominator; ... public Fraction multiply(Fraction that) { traceEnter("multiply", new Object[] {that}); Fraction result = new Fraction( this.numerator * that.numerator, this.denominator * that.denominator); result = result.reduceToLowestTerms(); traceExit("multiply", result); return result; } ...}

Page 5: Programmation par aspects
Page 6: Programmation par aspects

Préoccupations

Préoccupations métier :

Effectuer des paiements : débiter un montant d'un compte défini

Préoccupations techniques :

Traces

Intégrité de la transaction

Identification / authentification

Sécurité (confidentialité)

Performance

etc.

Page 7: Programmation par aspects

Dispersion / entrelacement des préoccupations

Chaque objet métier gère ses propres contraintes techniques (à son niveau) :

les préoccupations sont dispersées / entrelacées

Les applications sont plus difficiles à :

Concevoir / coder

Comprendre

Maintenir

Faire évoluer...

Page 8: Programmation par aspects

Symptômes

L’embrouillement du code– Les objets métiers interagissent simultanément avec de

nombreuses préoccupations techniques– Présence simultanée d’éléments de chaque préoccupation

dans le code

L’étalement du code– Les préoccupations entrelacées, s’étalent sur de nombreux

modules. – Leur implémentation s’étale elle aussi sur de nombreux

objets

Page 9: Programmation par aspects

Conséquences

Redundant code– Same fragment of code in many places

Difficult to reason about– Non-explicit structure– The big picture of the tangling isn’t clear

Difficult to change– Have to find all the code involved...– ...and be sure to change it consistently– ...and be sure not to break it by accident

Inefficient when crosscuting code is not needed

Page 10: Programmation par aspects

Solutions actuelles

mix-in classes– Une classe qui fournit des fonctionnalités à être héritées par une autre

classe, mais qui n’a pas de raisons d’être en soi. – Inheriting from a mixin is not a form of specialization but is rather a

means to collect functionality.

design patterns– Exemple Visitor et Template Method permettent de différer

l’implémentation

domain-specific solutions – frameworks and application servers,

let developers address some crosscutting concerns in a modularized way. The Enterprise JavaBeans (EJB) architecture, for example, addresses

crosscutting concerns such as security, administration, performance, and container-managed persistence.

Page 11: Programmation par aspects

Introduction

What is a crosscutting concern?

– Behavior that cuts across the typical divisions of responsibility, such as logging or debugging

– A problem which a program tries to solve.

– Aspects of a program that do not relate to the core concerns directly, but which proper program execution nevertheless requires.

Page 12: Programmation par aspects

LanguageDynamic VS Static crosscutting

Dynamic crosscutting– define additional behavior to run at certain well-defined

points in the execution of the program

Static crosscutting– modify the static structure of a program

adding new methods, implementing new interfaces, modifying the class hierarchy, etc.

Page 13: Programmation par aspects

Programmation par aspects

Implémenter des préoccupations de façon indépendante

Combiner ces implémentation pour former le système final

L’AOP est l’évolution logique de la programmation orientée objet

Page 14: Programmation par aspects

Etapes de développement de l’AOP

Identifier le préoccupations métier (classes) et techniques (aspects)

Implémenter chaque préoccupation séparément

Tisser les différentes préoccupations

Page 15: Programmation par aspects

Deux approches de l’AOP

AspectJ JAC

Extension du langage Java Framework AOP, serveur d’applications

Nouvelle grammaire pour exprimer les aspects

Aspects écrits en pur Java

Travaille sur le code source. Chaque modification nécessite une recompilation

Travaille sur le bytecode, permet de modifier, d’ajouter ou de retirer des aspects

dynamiquement

Ne gère pas la distribution Distribue automatiquement les aspects sur des serveurs distants

Permet uniquement le développement d’aspects

Permet le développement et la configuration des aspects

Support IDE pour JBuilder, Forte, et Emacs IDE UML gérant les aspects

Pas d’aspects pré-développés configurables Ensemble d’aspects pré-développés configurables

Version courante 1.0.5 Version courante 0.9.1

Open Source Mozilla Public License LGPL

Page 16: Programmation par aspects

Aspect J

Page 17: Programmation par aspects
Page 18: Programmation par aspects
Page 19: Programmation par aspects

The Figure Element example

Page 20: Programmation par aspects

Example I

A pointcut named move that chooses various method calls:– pointcut move():

call(void FigureElement.setXY(int,int)) || call(void Point.setX(int)) || call(void Point.setY(int)) || call(void Line.setP1(Point)) || call(void Line.setP2(Point));

Advice (code) that runs before the move pointcut:– before(): move() {

System.out.println("About to move");}

Advice that runs after the move pointcut:– after(): move() {

System.out.println("Just successfully moved");}

Page 21: Programmation par aspects
Page 22: Programmation par aspects

LanguageJoin Points

Well-defined points in the execution of a program:– Method call, Method execution– Constructor call, Constructor execution– Static initializer execution – Object pre-initialization, Object initialization– Field reference, Field set– Handler execution– Advice execution

Page 23: Programmation par aspects

LanguageJoin Points

public class Point { private int x; private int y;

public Point(int x, int y) { this.x = x; this.y = y;} public void incrXY(int dx, int dy){ x=+dx; y=+dy;} …}

public class Test{ public static void main(String[] args) { Point pt1 = new Point(0,0);

} } pt1.incrXY(3,6);

Method-execution

“Test.main(..)”

Staticinitialization

“Point._clinit_”

Constructor-call

“Point(..)”

Preinitialization

“Point(..)” Initialization

“Point(..)”

Constructor-execution

“Point(..)”

Field-set

“Point.x”Field-set

“Point.y”

Method-call

“Point.incrXY(..)”

Method-execution

“Point.incrXY(..)”Field-set

“Point.y”

Field-set

“Point.x”

Page 24: Programmation par aspects
Page 25: Programmation par aspects

Join points

A join point is a well-defined point in the program flow– We want to execute some code (“advice”) each time a join point is

reached– We do not want to clutter up the code with explicit indicators

saying “This is a join point”– AspectJ provides a syntax for indicating these join points “from

outside” the actual code A join point is a point in the program flow “where something

happens”– Examples:

When a method is called When an exception is thrown When a variable is accessed

Page 26: Programmation par aspects
Page 27: Programmation par aspects
Page 28: Programmation par aspects

Example pointcut designators I

When a particular method body executes:– execution(void Point.setX(int))

When a method is called:– call(void Point.setX(int))

When an exception handler executes:– handler(ArrayOutOfBoundsException)

When the object currently executing (i.e. this) is of type SomeType: – this(SomeType)

Page 29: Programmation par aspects

Example pointcut designators II

When the target object is of type SomeType – target(SomeType)

When the executing code belongs to class MyClass – within(MyClass)

When the join point is in the control flow of a call to a Test's no-argument main method– cflow(call(void Test.main()))

Page 30: Programmation par aspects
Page 31: Programmation par aspects

Pointcut designator wildcards

It is possible to use wildcards to declare pointcuts:– execution(* *(..))

Chooses the execution of any method regardless of return or parameter types

– call(* set(..)) Chooses the call to any method named set regardless

of return or parameter type In case of overloading there may be more than one such

set method; this pointcut picks out calls to all of them

Page 32: Programmation par aspects

Pointcut designators based on types

You can select elements based on types. For example,– execution(int *())

Chooses the execution of any method with no parameters that returns an int

– call(* setY(long)) Chooses the call to any setY method that takes a long as an argument,

regardless of return type or declaring type

– call(* Point.setY(int)) Chooses the call to any of Point’s setY methods that take an int as an

argument, regardless of return type

– call(*.new(int, int)) Chooses the call to any classes’ constructor, so long as it takes exactly

two ints as arguments

Page 33: Programmation par aspects

Pointcut designator composition

Pointcuts compose through the operations or (“||”), and (“&&”) and not (“!”)

Examples:– target(Point) && call(int *())

Chooses any call to an int method with no arguments on an instance of Point, regardless of its name

– call(* *(..)) && (within(Line) || within(Point)) Chooses any call to any method where the call is made from the code in Point’s or

Line’s type declaration

– within(*) && execution(*.new(int)) Chooses the execution of any constructor taking exactly one int argument, regardless

of where the call is made from

– !this(Point) && call(int *(..)) Chooses any method call to an int method when the executing object is any type

except Point

Page 34: Programmation par aspects

Pointcut designators based on modifiers

call(public * *(..)) – Chooses any call to a public method

execution(!static * *(..)) – Chooses any execution of a non-static method

execution(public !static * *(..)) – Chooses any execution of a public, non-static method

Pointcut designators can be based on interfaces as well as on classes

Page 35: Programmation par aspects

Kinds of advice

AspectJ has several kinds of advice; here are some of them:– Before advice runs as a join point is reached, before the program

proceeds with the join point

– After advice on a particular join point runs after the program proceeds with that join point

after returning advice is executed after a method returns normally after throwing advice is executed after a method returns by throwing

an exception after advice is executed after a method returns, regardless of whether

it returns normally or by throwing an exception

– Around advice on a join point runs as the join point is reached, and has explicit control over whether the program proceeds with the join point

Page 36: Programmation par aspects

Example II, with parameters

You can access the context of the join point:

pointcut setXY(FigureElement fe, int x, int y): call(void FigureElement.setXY(int, int)) && target(fe) && args(x, y);

after(FigureElement fe, int x, int y) returning: setXY(fe, x, y) { System.out.println(fe + " moved to (" + x + ", " + y + ").");}

Page 37: Programmation par aspects

Introduction

An introduction is a member of an aspect, but it defines or modifies a member of another type (class). With introduction we can– add methods to an existing class– add fields to an existing class– extend an existing class with another– implement an interface in an existing class– convert checked exceptions into unchecked

exceptions

Page 38: Programmation par aspects

Example introduction

aspect CloneablePoint {

declare parents: Point implements Cloneable;

declare soft: CloneNotSupportedException: execution(Object clone());

Object Point.clone() { return super.clone(); }}

Page 39: Programmation par aspects

Approximate syntax

An aspect is: aspect nameOfAspect { body }– An aspect contains introductions, pointcuts, and advice

A pointcut designator is: when(signature)– The signature includes the return type– The “when” is call, handler, execution, etc.

A named pointcut designator is: name(parameters): pointcutDesignator

Advice is: adviceType(parameters): pointcutDesignator { body }

Introductions are basically like normal Java code

Page 40: Programmation par aspects
Page 41: Programmation par aspects
Page 42: Programmation par aspects

Example aspect I

aspect PointWatching {

private Vector Point.watchers = new Vector();

public static void addWatcher(Point p, Screen s) { p.Watchers.add(s); }

public static void removeWatcher(Point p, Screen s) { p.Watchers.remove(s); }

static void updateWatcher(Point p, Screen s) { s.display(p); }// continued on next slide

Page 43: Programmation par aspects

Example aspect II

// continued from previous slide

pointcut changes(Point p): target(p) && call(void Point.set*(int));

after(Point p): changes(p) { Iterator iter = p.Watchers.iterator(); while ( iter.hasNext() ) { updateWatcher(p, (Screen)iter.next()); } }}

Page 44: Programmation par aspects

Références

The AspectJTM Programming Guide– http://www.eclipse.org/aspectj/doc/released/progguide/index.html

I want my AOP!– http://www.javaworld.com/javaworld/jw-01-2002/jw-0118-aspect.html

Aspect-Oriented Programming with AspectJ™– http://dolphin.c.u-tokyo.ac.jp/~kazu0/aspectj/doc/tutorial/aspectj-tutorial.pdf

www.cs.cmu.edu/~aldrich/courses/819/slides/aspectj.ppt

http://www.eclipse.org/ajdt/demos/HelloWorldAspectJ.html

Page 45: Programmation par aspects

LanguagePointcuts

A set of join point, plus, optionally, some of the values in the execution context of those join points.

Can be composed using boolean operators || , &&

Matched at runtime

Page 46: Programmation par aspects

LanguageAdvice

Method-like mechanism used to declare that certain code should execute at each of the join points in the pointcut.

Advice:– before– around– after

after after returning after throwing

Page 47: Programmation par aspects

LanguageAdvice

Method-like mechanism used to declare that certain code should execute at each of the join points in the pointcut.

Advice:– before– around– after

after after returning after throwing

Page 48: Programmation par aspects

LanguagePointcut parameters and thisJoinPoint

thisJoinPoint

Simple reflective access to information about the current join point. Notice that this is very useful for debugging and tracing purposes.

before():call(void Point.setX(int)){

if(((Integer)thisJoinPoint.getArgs()[0]).intValue()>10)

elseSystem.out.println("x value of ”+thisJoinPoint.getTarget() +" will be set to”

+thisJoinPoint.getArgs()[0]);}

System.out.println("The value is too big !");

Page 49: Programmation par aspects

LanguageWildcards and cflow

Wildcards– call( * Point. *(..))– call( public * com.xerox.scanner.*.*(..))– call( * Point.get*())

Page 50: Programmation par aspects

LanguageWildcards and cflow

Control-flow– pointcut moveContext(): cflow(move())

picks out each join point that occurs in the dynamic context of the join points picked out by move().

Page 51: Programmation par aspects

LanguageWildcards and cflow

Control-flow belowpointcut moves(FigureElement fe):

…);

pointcut topLevelMoves(FigureElement fe):target(fe)&&moves(FigureElement)&&!cflowbelow(moves(FigureElement));

before(FigureElement fe):target(fe)&&topLevelMoves(FigureElement)}

{System.out.println("top level moves");

target(fe)&&

Page 52: Programmation par aspects

LanguageInheritance and Overriding of Advice and pointcuts

Abstract aspect & Abstract pointcutsabstract aspect SimpleTracing{ abstract pointcut tracePoints(); before(): tracePoints() { printMessage(“Entering”,thisJoinPoint); } after(): tracePoints(){

printMessage(“Exiting”,thisJoinPoint); }

void printMessage(Stringwhen,JoinPoint jpt){ code to print an informative message using information

from the joinpoint }

}

Page 53: Programmation par aspects

LanguageInheritance and Overriding of Advice and pointcuts

Concrete implementation of the aspect:

aspect IncrXYTracing extends SimpleTracing{

pointcut tracePoints():

call(void FigureElement.incrXY(int, int));

}

Page 54: Programmation par aspects

Conséquences

Poor traceability: Simultaneously implementing several concerns obscures the correspondence between a concern and its implementation, resulting in a poor mapping between the two.

Lower productivity: Simultaneous implementation of multiple concerns shifts the developer's focus from the main concern to the peripheral concerns, leading to lower productivity.

Less code reuse: Since, under these circumstances, a module implements multiple concerns, other systems requiring similar functionality may not be able to readily use the module, further lowering productivity.

Poor code quality: Code tangling produces code with hidden problems. Moreover, by targeting too many concerns at once, one or more of those concerns will not receive enough attention.

More difficult evolution: A limited view and constrained resources often produce a design that addresses only current concerns. Addressing future requirements often requires reworking the implementation. Since the implementation is not modularized, that means touching many modules. Modifying each subsystem for such changes can lead to inconsistencies. It also requires considerable testing effort to ensure that such implementation changes have not caused bugs.