Académique Documents
Professionnel Documents
Culture Documents
Cet article est consacr la programmation oriente aspect. Il prsente d'abord, d'une manire indpendante de l'implmentation, les principaux concepts de l'AOP puis, illustre ces concepts avec des mises en uvre pratiques en langage AspectJ travers un exemple d'application.
I - Introduction..............................................................................................................................................................3 I-A - Proccupations transversales........................................................................................................................ 4 I-A-1 - Enchevtrement du code (code tangling)............................................................................................. 4 I-A-2 - parpillement du code (code scattering).............................................................................................. 5 I-B - Mthodologie de l'AOP.................................................................................................................................. 5 II - Concepts................................................................................................................................................................ 6 II-A - Aspect............................................................................................................................................................6 II-B - Point de jonction (joinpoint).......................................................................................................................... 6 II-C - Coupe (pointcut)........................................................................................................................................... 7 II-D - Code advice (advice code)...........................................................................................................................7 II-E - Mcanisme d'introduction..............................................................................................................................8 II-F - Tissage (weaving)......................................................................................................................................... 8 III - AspectJ..................................................................................................................................................................8 III-A - Historique et origine..................................................................................................................................... 8 III-B - Tlchargement et installation de l'outil.......................................................................................................9 III-C - Prsentation gnrale.................................................................................................................................. 9 III-D - Point de jonction........................................................................................................................................ 10 III-E - Coupe......................................................................................................................................................... 11 III-F - Advice......................................................................................................................................................... 12 III-G - Dclaration inter-type.................................................................................................................................13 III-H - Aspect........................................................................................................................................................ 13 IV - Exemple d'application......................................................................................................................................... 14 IV-A - Introduction................................................................................................................................................ 14 IV-B - Le systme d'arbre d'expression...............................................................................................................14 IV-C - La proccupation "cache"..........................................................................................................................16 IV-D - Excution sans cache............................................................................................................................... 19 IV-E - Excution avec cache................................................................................................................................20 V - Conclusion........................................................................................................................................................... 20 VI - Tlchargement des sources............................................................................................................................. 21 VII - Liens connexes..................................................................................................................................................21 VIII - Remerciements................................................................................................................................................. 21 IX - Commentaires des lecteurs................................................................................................................................21
-2Copyright 2009 Developpez LLC. Tous droits rservs Developpez LLC. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts. Cette page est dpose la SACD.
http://skebir.developpez.com/tutoriels/java/aspectj/
I - Introduction
Depuis une trentaine d'annes, l'approche oriente objet a procur des bnfices indnombrables dans la communaut gnie logicielle. En effet, elle permet de modulariser de larges systmes d'une manire intuitive car elle offre un modle de programmation riche trs proche du monde rel. Aujourd'hui, l'orient objet bnficie d'un excellent background notamment grce la popularisation d'UML. En plus, une multitude de langages de programmation (Java, C++, Smalltalk, ...) ont adopt ce paradigme de manire native. Cependant, l'approche oriente objet montre ses limites et choue face la modularisation des proccupations transversales au systme. Parmi les proccupations transversales plus courantes, on trouve la scurit, la gestion transactionnelle de la persistance, la synchronisation, le logging (Figure). Ces proccupations ont la particularit d'un ct, d'tre disperses travers plusieurs modules, et d'un autre ct, d'tre enchevtres avec les modules mtiers du systme. Ces deux phnomnes dgradent considrablement le maintien, la comprhension et l'volutivit du code.
Proccupations transversales C'est l que la programmation oriente aspect intervient en apportant des mcanismes la fois simples apprhender et puissants qui permettent de capturer des proccupations transversales. En effet, l'oriente aspect procure une solution lgante aux problmes d'enchevtrement et d'parpillement du code. Aujourd'hui, cette technique d'ingnierie logicielle s'affirme comme tant la prochaine tape pour le dcoupage des systmes en offrant une nouvelle dimension pour la modularisation notamment avec la notion d'aspect. En effet, paralllement aux classes qui sont un support idal pour modulariser les proccupations mtiers du systme, les aspects sont un support pour capturer les proccupations transversales. Dans une dmarche oriente aspect, les proccupations transversales peuvent voluer indpendamment des proccupations mtier et vice-versa (Figure). Et afin, que l'application finale prennent en compte toutes les proccupations, le systme passe par une tape dite de tissage d'aspects. Durant cette tape, les proccupations transversales encapsules dans les aspects vont tre tisses ou intgres dans les proccupations mtiers.
Sparation des proccupations transversales et mtiers Actuellement, une panoplie de langages et de plateformes orientes aspects existe (AspectJ, AspectWerkz, AspectC++, ...). Dans cet article, nous allons nous intresser au langage AspectJ qui est notre connaissance
-3Copyright 2009 Developpez LLC. Tous droits rservs Developpez LLC. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts. Cette page est dpose la SACD.
http://skebir.developpez.com/tutoriels/java/aspectj/
l'exprimentation la plus aboutie de langages orients aspects. Ce n'est pas un langage part entire mais une extension du langage Java qui permet ce dernier de supporter la programmation oriente aspect. Dans cet article, nous allons tout d'abord nous intresser dans la section aux concepts de la programmation oriente aspect savoir les points de jonction, les coupes et les codes advices. La prsentation de ses concepts sera indpendante de toute implmentation afin de faciliter leur apprhension. Puis, nous nous intresserons dans la section au langage AspectJ en prsentant l'implmentation des principaux concepts de l'AOP travers ce langage. Et enfin, nous terminerons dans la section par un exemple pratique d'une application oriente aspect. Mais avant, nous allons voir les problmes engendrs par la non modularisation des proccupations transversales ainsi que la mthodologie gnrale d'une dmarche oriente aspect.
Enchevtrement du code Un autre exemple pour illustrer l'enchevtrement du code est la notion d'espace multi dimensionnel de proccupations. Imaginons que les besoins sont projets sur un espace multi dimensionnel o chaque proccupation reprsente une dimension. Dans cet espace, chaque proccupation est indpendante et peut voluer sans affecter les autres proccupations. Par exemple, le changement du schma de scurit n'affecte pas la logique mtier. Cependant, un espace multidimensionnel de proccupation est rduit dans un espace uni dimensionnel d'implmentation (Figure).
-4Copyright 2009 Developpez LLC. Tous droits rservs Developpez LLC. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts. Cette page est dpose la SACD.
http://skebir.developpez.com/tutoriels/java/aspectj/
Espace des proccupations et espace d'implmentation Tant que l'espace d'implmentation est uni dimensionnel, on se concentre souvent sur l'implmentation de la proccupation qui a un rle dominant ; les autres proccupations sont alors enchevtres avec la proccupation dominante.
http://skebir.developpez.com/tutoriels/java/aspectj/
Etapes de dveloppement dans une mthodologie AOP 1 Dcomposition aspectuelle : Les besoins sont ici dcomposs pour identifier les proccupations fonctionnelles et transversales. Par exemple, un dveloppeur pourra identifier les proccupations suivantes : logique mtier, logging, cache, gestion transactionnelle de la persistance, authentification, etc. Ensuite, il pourra dcider que seule la logique mtier est une proccupation fonctionnelle. Toutes les autres proccupations sont des proccupations transversales au systme et qui vont tre utilises par plusieurs modules. Implmentation des proccupations : Chaque proccupation est implmente indpendamment des autres. Comme pour l'exemple du paragraphe prcdent, le dveloppeur aura implmenter la logique mtier, le logging, le cache, la gestion transactionnelle de la persistance, l'authentification, etc. Recomposition aspectuelle : Des rgles de recompositions sont spcifies en crant des units appeles aspects. Le processus de recomposition, aussi connu sous le nom de tissage ou d'intgration, utilise ces informations pour composer le systme final. Comme pour l'exemple prcdent, le dveloppeur peut crer une rgle qui s'assure que chaque opration effectue par la logique mtier doit d'abord tre mise en journal (logge).
2 3
-6Copyright 2009 Developpez LLC. Tous droits rservs Developpez LLC. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts. Cette page est dpose la SACD.
http://skebir.developpez.com/tutoriels/java/aspectj/
Bien que la dfinition d'un point de jonction dsigne un moment de l'excution, cette dfinition est base sur la structure d'un programme (ses classes, mthodes, attributs, etc.). Les catgories suivantes dcrivent les types de points de jonction communment rencontrs et qui sont indpendants de toute implmentation : Les mthodes : dans les langages orients objet, l'excution d'un programme peut tre considre comme une squence d'appels et d'excution de mthodes. Les diffrents scnarios d'excution d'une application peuvent tre exprims en termes de squences de messages qui dclenchent l'excution de mthodes. Les appels et les excutions de mthodes sont donc deux types de points de jonction couramment utiliss. Les constructeurs : les constructeurs sont principalement utiliss pour crer les instances des classes d'une application. Comme pour les mthodes, Les appels et les excutions d'un constructeur correspondent des types de points de jonction. Les attributs : les langages orients aspect considrent les oprations de lecture et d'criture sur les attributs comme des types de points de jonction. Un exemple concret d'utilisation de ce type de point de jonction est la gestion transactionnelle de la persistance. Les exceptions : les exceptions sont leves (throw) pour signaler une situation d'excution anormale et elles sont captures (catch}) pour excuter un traitement particulier. Ces deux vnements (le throw et le catch) sont des points d'excution trs importants dans une application. Ils sont tout les deux considrs par la plupart des langages orients aspect comme des types de points de jonction.
Les appels et les excutions de mthodes sont incontestablement les types de points de jonction les plus utiliss dans l'AOP. D'autres lments de codes, comme les boucles FOR et les instructions conditionnelles IF, qui dfinissent la structure d'un programme sont considrs de trs faible granularit pour tre utiliss pour dfinir des points de jonction. En conclusion, tous les programmes, mmes les plus simples, contiennent plusieurs points de jonction diffrents. La tche du dveloppeur est de slectionner les points de jonction qui sont utiles pour implmenter un aspect donn. Cette slection est ralise grce la notion de coupe (pointcut), qui est prsente dans le paragraphe suivant.
-7Copyright 2009 Developpez LLC. Tous droits rservs Developpez LLC. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts. Cette page est dpose la SACD.
http://skebir.developpez.com/tutoriels/java/aspectj/
Un code advice peut tre excut selon trois modes : avant, aprs, ou autour d'un point de jonction. Lorsqu'il est excut autour du point de jonction, il peut carrment remplacer l'excution de ce dernier, ou bien lui redonner le contrle.
http://skebir.developpez.com/tutoriels/java/aspectj/
plusieurs versions d'AspectJ ont vu le jour, et chacune apportait de nouvelles fonctionnalits et corrigeait les bugs de la prcdente. La premire version officielle d'AspectJ, dsign AspectJ 1.0, a t ralise en novembre 2001, Durant cette anne, l'AOP a t compltement reconnue par la communaut informatique mondiale, et une dition spciale du journal Communications of the ACM a t ddie l'AOP. En dcembre 2002, le projet AspectJ a quitt XEROX PARC et a rejoint la communaut open-source Eclipse. Et depuis, le plugin Eclipse AspectJ Developpement Tools (AJDT) est dvelopp. Ce plugin intgre AspectJ et permet d'crire, de compiler et d'excuter des programmes orient aspects dans l'environnement de dveloppement Eclipse.
Installation d'AspectJ A la fin de l'installation, il est recommand de mettre le rpertoire %aspectj_folder%/bin dans la variable d'environnement path afin de pouvoir l'utiliser dans la ligne de commande partir de n'importe quel chemin.
-9Copyright 2009 Developpez LLC. Tous droits rservs Developpez LLC. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts. Cette page est dpose la SACD.
http://skebir.developpez.com/tutoriels/java/aspectj/
Transversalit statique : La transversalit statique consiste augmenter la structure des classes. Pour cela AspectJ offre la notion de mcanisme d'introduction qui permet entre autres d'ajouter des lments structuraux comme des attributs ou des mthodes aux classes. Le mcanisme d'introduction d'AspectJ permet aussi d'ajouter des liens entre des classes comme l'hritage et l'implmentation d'interfaces. Concrtement, AspectJ offre un support simple et facile apprhender pour implmenter ce genre de transversalit. Transversalit dynamique : La transversalit dynamique consiste augmenter le comportement des classes. Pour cela AspectJ offre les notions de coupes et de code advices. Les coupes servent slectionner des points prcis dans les classes. Et les advices iront se greffer avant, aprs ou autour de ces points afin d'tendre leur comportement.
Dans ce qui suit, nous allons aborder les principaux concepts de ce langage et leur mise en oeuvre pratique. Pour cela, tous le exemples qui seront prsents reposeront sur le diagramme de classes de la figure suivante.
- 10 Copyright 2009 Developpez LLC. Tous droits rservs Developpez LLC. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts. Cette page est dpose la SACD.
http://skebir.developpez.com/tutoriels/java/aspectj/
Point de jonction Method call Method execution Constructor call Constructor execution Static initializer execution Object pre-initialization Object initialization Field reference Field set Handler execution Advice execution
Description Quand une mthode est appele Quand le corps d'une mthode est execut Quand un constructeur est appel Quand le corps d'un constructeur est execut Quand l'initialisation statique d'une classe est excute Avant l'initialisation de l'objet Quand l'initialisation d'un objet est excute Quand un attribut non-constant d'une classe est rfrenc Quand un attribut d'une classe est modifi Quand un traitement d'une exception est excut Quand le code d'un advice est excut
Dans AspectJ, Tout les points de jonction ont un contexte associ eux. Par exemple, le contexte d'un point de jonction correspondant un appel de mthode contient l'objet appelant, l'objet appel, et les arguments de la mthode. De la mme manire, le contexte d'un point de jonction correspondant au traitement d'une exception contient l'objet courant, et l'exception leve.
III-E - Coupe
Dans AspectJ, les coupes corresdpondent plusieurs points de jonctions dans le flot d'un programme. Par exemple, la coupe :
call(void Point.setX(int))
capture chaque points de jonctions correspondant un appel la mthode setX() de la classe Point qui ne retourne aucune valeur void et qui a comme paramtre un entier (int). Une coupe peut tre construite partir d'autre coupes en utilisant les oprateurs and, or et not (respectivement &&, || et !). Par exemple, la coupe :
call(void Point.setX(int)) || call(void Point.setY(int))
Dsigne les points de jonction correspondant un appel la mthode Point.setX() ou un appel la mthode Point.setY(). Les coupes peuvent identifier des points de jonction de diffrentes classes, en d'autres termes, elles peuvent tre transverses aux classes. Par exemple, la coupe :
call(void call(void call(void call(void call(void FigureElement.incrXY(int,int)) Point.setX(int)) Point.setY(int)) Line.setP1(Point)) Line.setP2(Point)) || || || ||
capture chaque point de jonction qui est un appel une des cinq mthodes (la premire mthode est une mthode d'interface). Dans le dernier exemple, la coupe capture tous les points de jonction correspondant au mouvement d'un objet de type FigureElement. AspectJ permet de dclarer des coupes nommes avec le mot-cl pointcut, afin qu'elles puissent tre rutilises sans avoir les redfinir. Les instructions suivantes dclarent une coupe nomme :
- 11 Copyright 2009 Developpez LLC. Tous droits rservs Developpez LLC. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts. Cette page est dpose la SACD.
http://skebir.developpez.com/tutoriels/java/aspectj/
pointcut move(): call(void FigureElement.incrXY(int,int)) call(void Point.setX(int)) call(void Point.setY(int)) call(void Line.setP1(Point)) call(void Line.setP2(Point));
|| || || ||
Ainsi, on peut appeler n'importe quel moment la coupe nomme move(). Jusque l, les coupes que nous avons donnes taient bases sur une numration explicite d'un ensemble de signature de mthodes. AspectJ offre aussi un mcanisme qui permet de spcifier des coupes en termes de proprits de mthodes autres que leur nom exact. La faon la plus simple de le faire est d'utiliser les expressions rgulires pour exprimer les champs de la signature des mthodes. Par exemple, la coupe :
call(void Point.set*(..))
capture chaque point de jonction correspondant un appel d'une mthode ne retournant aucun rsultat (void) et appartenant la classe Point et commenant par la chaine set, quelque soit le type et le nombre de ses paramtres. La coupe :
call(public * Line.* (..))
capture tout les appels aux mthodes publiques (public) de la classe Line. Les exemples prcdents ne font appel qu' un seul type de coupe qui est l'appel de mthode (i.e. call). Il existe d'autres types de coupes dans AspectJ comme : l'excution de mthode (ex : execution(void Point.setX(..))), ou l'accs aux attributs (ex : get(Point.x)), etc.
III-F - Advice
Les coupes capturent les points de jonction, mais elles ne font rien de plus. Pour implmenter un comportement transversal, on utilise les advices. En effet, un advice fait correspondre une coupe (i.e. un ensemble de points de jonction) un bout de code excut chaque point de jonction de cette coupe. Un code advice est un bloc d'instruction associ une coupe. Il est excut avant, aprs ou autour des points de jonction slectionns par la coupe qui lui est associe. AspectJ offre 3 types de codes advice : before, after et around. Les codes advice de type before (respectivement after) permettent d'introduire un comportement avant (respectivement aprs) un point de jonction. Cependant les codes advice de type after se dclinent en 2 variantes : after returning et after throwing qui signifient respectivement aprs le retour d'une mthode sans exception et avec exception. Un advice de type around quant lui dfinit un bloc d'instructions qui s'excute autour d'un point de jonction. Il permet ventuellement de remplacer carrment l'excution d'une mthode. AspectJ fournit la mthode proceed() qui permet de rendre le contrle de l'excution au point de jonction dans un code advice de type around. Le code suivant montre un exemple d'advice de type before, qui utilise la coupe move() dfinit prcdemment :
before() : move() { System.out.println("Figure sur le point d'tre dplace");}
Nous avons dit prcdemment qu' chaque point de jonction est associ un contexte d'excution (cf. section ) contenant par exemple les arguments de la mthode si le point de jonction en est une. Dans AspectJ, ce contexte est accessible via les trois coupes primitives : this, target, args. Ce contexte s'avre trs utile lorsqu'on veut par exemple, accder aux paramtres d'une mthode dans un code advice. L'advice suivant :
- 12 Copyright 2009 Developpez LLC. Tous droits rservs Developpez LLC. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts. Cette page est dpose la SACD.
http://skebir.developpez.com/tutoriels/java/aspectj/
after(int x,int y) returning : call(void FigureElement.incrXY(int,int) && args(x,y) { System.out.println("la figure a t dplac de +"x"+","+y); }
rcupre les arguments de la mthode incrXY(int,int) dans les variables x et y et peut faire n'importe quel traitement avec ces valeurs. Les coupes primitives this et target permettent respectivement de rcuprer l'objet courant et l'objet cible du contexte d'excution pour le point de jonction. Le tableau suivant rsume la signification de l'objet courant, de l'objet cible et des arguments pour chaque type de points de jonction. Point de jonction Method Call Method Execution Constructor Call Constructor Execution Static initializer execution Object preinitialization Object initialization Field reference Field assignment Handler execution Advice execution Objet courant L'objet appelant L'objet appelant L'objet appelant L'objet appelant Nant Nant L'objet appelant L'objet appelant L'objet appelant L'objet appelant L'aspect appelant Objet cible L'objet appel L'objet appel Nant L'objet appelant Nant Nant L'objet appelant L'objet appel L'objet appel L'objet appelant L'aspect appelant Arguments Les arguments de la mthode Les arguments de la mthode Les arguments du constructeur Les arguments du constructeur Nant Les arguments du constructeur Les arguments du constructeurs Nant La valeur assigne L'exception leve Les arguments de l'advice
L'instruction suivante permet de dclarer que les classes Point et Line hritent de la classe GeometricObject :
declare parents : (Point || Line) extends GeometricObject ;
III-H - Aspect
Dans AspectJ. Un aspect contient tout les ingrdients ncessaires pour la dfinition d'une proccupation transversale savoir : les dfinitions de coupes, les codes advice et les dclarations inter-types. Il peut aussi ventuellement contenir des attributs et des mthodes qui lui sont propres. Le code suivant montre un exemple d'aspect ralisant la proccupation de mise jour d'affichage :
aspect UpdateDisplay {
- 13 Copyright 2009 Developpez LLC. Tous droits rservs Developpez LLC. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts. Cette page est dpose la SACD.
http://skebir.developpez.com/tutoriels/java/aspectj/
pointcut move(FigureElement elem) : target (elem) && ( call ( void Line.setP1 (Point) ) || call ( void Line.setP2 (Point) ) || call ( void Point.setX (int) ) || call ( void Point.setY (int) ) || call ( void FigureElement.incrXY(int, int) ) ) ; after(FigureElement elem) returning : move ( elem ) { Display.update(elem); }
Systme d'arbre d'expression Le code source correspondant aux trois classes du systme est trs simple et est prsent ci-dessous. Expression.java
package org.sdf; public abstract class Expression { public abstract int eval(); }
Plus.java
package org.sdf; public class Plus extends Expression { private Expression leftExpression;
- 14 Copyright 2009 Developpez LLC. Tous droits rservs Developpez LLC. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts. Cette page est dpose la SACD.
http://skebir.developpez.com/tutoriels/java/aspectj/
Plus.java
private Expression rightExpression; public Plus(Expression leftExpression, Expression rightExpression) { super(); this.leftExpression = leftExpression; this.rightExpression = rightExpression; } public Expression getLeftExpression() { return leftExpression; } public void setLeftExpression(Expression leftExpression) { this.leftExpression = leftExpression; } public Expression getRightExpression() { return rightExpression; } public void setRightExpression(Expression rightExpression) { this.rightExpression = rightExpression; } @Override public int eval() { System.out.println("Evaluation d'un noeud"); return leftExpression.eval() + rightExpression.eval(); }
Number.java
package org.sdf; public class Number extends Expression { private int value; public Number(int value) { this.value = value; } public void setValue(int value) { this.value = value; } @Override public int eval() { System.out.println("Evaluation d'un noeud"); return value; }
http://skebir.developpez.com/tutoriels/java/aspectj/
Main.java
} }
Plus plus1 = new Plus(dix,neuf); Plus plus2 = new Plus(plus1,cinq); // au dbut, defaut de cache obligatoire System.out.println("premier appel"); System.out.println(plus2.eval()); // on a un cache valide, donc on le consulte au lieu de parcourir l'arbre System.out.println("deusieme appel"); System.out.println(plus2.eval()); // on va altrer la valeur du noeud cinq // qui va conduire invalider son cache ainsi que celui de operation2 cinq.setValue(4); System.out.println("troisieme appel"); System.out.println(plus2.eval());
http://skebir.developpez.com/tutoriels/java/aspectj/
public int Expression.getCache() { return cache; } public void Expression.setCache(int cache) { this.cache = cache; } public boolean Expression.isCacheValid() { return cacheValid; } public void Expression.validateCache() { this.cacheValid = true; }
En plus de ces deux variables, chaque nud devra connaitre l'identit de son pre afin qu'il puisse lui signaliser que son cache n'est plus valide, ce qui va impliquer aussi l'invalidation du cache du pre et vice-versa jusqu' la racine. Ceci est fait en dclarant une variable appele ancestor qui pointera vers le pre du nud, et une mthode qui permet d'invalider le cache des ascendants (s'ils existent) en cascade, comme suit :
private Expression Expression.ancestor = null; public void Expression.invalidateCache() { cacheValid = false; if (this.getAncestor()!=null) this.getAncestor().invalidateCache(); } public Expression Expression.getAncestor() { return ancestor; } public void Expression.setAncestor(Expression ancestor) { this.ancestor = ancestor; }
L'invalidation du cache devra survenir aprs chaque changement de valeur d'un nud. Le changement de valeur d'un nud consiste en l'appel d'une des mthodes : Number.setValue(); Plus.setLeftExpression(); Plus.setRightExpression();
Et l'advice correspondant cette coupe devra appeler la mthode invalidateCache() sur l'objet exp (objet sur lequel la mthode a t appele et rcupre avec la coupe primitive target) aprs chaque occurrence de l'un des points de jonction de la coupe. Il est dclar comme suit :
after(Expression exp):changeValue(exp) { exp.invalidateCache(); }
Afin de pouvoir consulter le cache avant d'valuer les fils gauches et droits, on devra capturer chaque point de jonction correspondant un appel la mthode eval(). Ceci est effectu grce la coupe suivante :
- 17 Copyright 2009 Developpez LLC. Tous droits rservs Developpez LLC. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts. Cette page est dpose la SACD.
http://skebir.developpez.com/tutoriels/java/aspectj/
Et l'advice correspondant cette coupe doit d'abord voir si le cache est valide. Si ce n'est pas le cas, il appelle la mthode originale avec proceed() pour valuer la valeur des sous-arbres, puis il affecte cette valeur au cache, le valide et retourne sa valeur. Il est dclar comme suit :
int around(Expression exp):evaluation(exp) { if (!exp.isCacheValid()) { int result = proceed(exp); exp.setCache(result); exp.validateCache(); } return exp.getCache(); }
La dernire chose faire consiste crer un lien entre un nud et son pre. Pour cela, on devra capturer tous les points de jonction correspondant au constructeur de la classe Plus. Ceci est fait avec la coupe suivante :
pointcut PlusCreation(Plus exp): this(exp) && execution(Plus.new(Expression,Expression));
Et l'advice correspondant devra lier le pre aux fils, en utilisant la mthode setAncestor() dclare prcdemment, comme suit :
after(Plus exp) : PlusCreation(exp) { exp.getLeftExpression().setAncestor(exp); exp.getRightExpression().setAncestor(exp); }
Voil, il ne reste plus qu' mettre tous ces petits bouts de code dans un mme module (ou aspect). Ce qui va rsulter en ceci : Caching.aj
package org.sdf; public aspect Caching { private int Expression.cache; private boolean Expression.cacheValid = false; private Expression Expression.ancestor = null; public int Expression.getCache() { return cache; } public void Expression.setCache(int cache) { this.cache = cache; } public boolean Expression.isCacheValid() { return cacheValid; } public void Expression.validateCache() { this.cacheValid = true; } public void Expression.invalidateCache() { cacheValid = false; if (this.getAncestor()!=null) this.getAncestor().invalidateCache();
- 18 Copyright 2009 Developpez LLC. Tous droits rservs Developpez LLC. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts. Cette page est dpose la SACD.
http://skebir.developpez.com/tutoriels/java/aspectj/
Caching.aj
} public Expression Expression.getAncestor() { return ancestor; } public void Expression.setAncestor(Expression ancestor) { this.ancestor = ancestor; } pointcut changeValue(Expression exp): target(exp) && ( call(public void Number.setValue(int)) || call(public void Plus.setLeftExpression(Expression)) || call(public void Plus.setRightExpression(Expression)) ); after(Expression exp):changeValue(exp) { exp.invalidateCache(); } pointcut evaluation(Expression exp): target(exp) && call(public int Expression.eval()); int around(Expression exp):evaluation(exp) { if (!exp.isCacheValid()) { int result = proceed(exp); exp.setCache(result); exp.validateCache(); } return exp.getCache(); } pointcut PlusCreation(Plus exp): this(exp) && execution(Plus.new(Expression,Expression)); after(Plus exp) : PlusCreation(exp) { exp.getLeftExpression().setAncestor(exp); exp.getRightExpression().setAncestor(exp); }
- 19 Copyright 2009 Developpez LLC. Tous droits rservs Developpez LLC. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts. Cette page est dpose la SACD.
http://skebir.developpez.com/tutoriels/java/aspectj/
Evaluation d'un Evaluation d'un Evaluation d'un 24 troisieme appel Evaluation d'un Evaluation d'un Evaluation d'un Evaluation d'un Evaluation d'un 23
On remarque qu' chaque appel, on devra visiter les cinq nuds de l'arbre.
noeud noeud
On remarque qu'au premier appel de eval(), on devra crer 5 dfauts de cache obligatoires. Mais au deuxime appel aucun nud n'est valu, la valeur 24 est extraite du cache et aucun parcours de l'arbre n'est effectu. Au troisime appel la valeur du nud cinq est altre donc la valeur de son cache et aussi celle du cache de son pre (le nud plus 2) sont invalides, ce qui rsulte en la rvaluation de seulement deux nuds dans l'arbre.
V - Conclusion
Dans cet article, nous avons fais un survol sur la programmation oriente aspect. Aprs avoir expliqu les problmes auxquels l'AOP apporte des solutions efficaces dans la section , nous avons abord les principaux concepts de ce paradigme dans la section en se basant sur des rfrences plus ou moins rcentes. Ensuite, nous avons prsent dans la section le langage AspectJ, ses origines, les notions qu'il apporte au langage de programmation Java. Nous avons vu la syntaxe de ses principales composantes accompagne de plusieurs exemples illustratifs. La section prsente un exemple concret d'implmentation d'une proccupation transversale dans un systme existant. Il s'agit d'implmenter un schma de cache dans un systme d'arbre d'expression, afin d'viter des parcours en profondeur. Pour cela, le systme a subit une volution sans perdre le moindre degr de maintenabilit ou de comprhensibilit. La proccupation transversale Cache a t exprime dans le langage AspectJ. Elle a t encapsule dans un seul module et le programme principal n'a subit aucune modification. Les rsultats empiriques ont montr la faisabilit de cette approche.
- 20 Copyright 2009 Developpez LLC. Tous droits rservs Developpez LLC. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts. Cette page est dpose la SACD.
http://skebir.developpez.com/tutoriels/java/aspectj/
VIII - Remerciements
Je remercie La Zlie et jacques_jean pour l'excellent travail qu'il ont effectue pour la relecture orthographique ainsi que Ricky81 et Baptiste Wicht pour leurs conseils et encouragements.
- 21 Copyright 2009 Developpez LLC. Tous droits rservs Developpez LLC. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts. Cette page est dpose la SACD.
http://skebir.developpez.com/tutoriels/java/aspectj/