Upload
skip
View
41
Download
1
Embed Size (px)
DESCRIPTION
LOG4430 : Architecture logicielle et conception avancée. Applications de base de la conception orientée aspect : surveillance, traçage et profilage. Applications de base de la conception orientée aspect. C ontexte Introduction aux aspects Conception par aspects Avantages et inconvénients. - PowerPoint PPT Presentation
Citation preview
Foutse Khomh
© Guéhéneuc, 2009; Arnaoudova, 2010; Khomh, 2010Département de génie informatique et de génie logicielÉcole Polytechnique de Montréal
LOG4430 :Architecture logicielle et
conception avancée
Applications de base de la
conception orientée aspect : surveillance,
traçage et profilage
2/82
Applications de base de la conception orientée aspect
1. Contexte
2. Introduction aux aspects
3. Conception par aspects
4. Avantages et inconvénients
3/82
1. Contexte
Pensez à la source de tous les maux en génie logiciel ?
4/82Following slides courtesy of Gregor Kiczales, original available at [http://www.cs.ubc.ca/~gregor/papers/kiczales-java-one-04-aop-panel.ppt]
1964 1974 20041984 1994
5/82
Vous pensez intuitivement a des objets ?– Points, lignes…– Surfaces de dessin
(Drawing)– GUI Widgets– …
Display
2Point
getX()getY()setX(int)setY(int)moveBy(int, int)
Line
getP1()getP2()setP1(Point)setP2(Point)moveBy(int, int)
Shape
moveBy(int, int)
*
1964 1974 20041984 1994
objects are intuitive
6/82
En 1969, la plupart des programmeurs auraient utilises la difficile conception et implantation suivante !
22 12
65 93
43 29
86 65
2 4
collection of procedures to operate on and
manage table entries
6 7 5 8
+
1964 1974 20041984 1994
objects are not intuitive objects are intuitive
7/82
La programmation par objets– Inventée en 1961– A peu près au même moment
que la programmation structurée
– Devient « par objets » en 1967– Rend le code de simulation
plus proche du modèle original
1964 1974 20041984 1994
OOPintuitivenot intuitive
8/82
Aparté
9/82
Aparté
Ole-Johan Dahl– 12 octobre 1931 – 29 juin 2002– Norvégien– Père de Simula et de la PPO– Récipiendaire
• ACM A.M. Turing Award• IEEE John von Neumann Medal
– Développe l’idée de la PPO dans les années 1950 au Centre de calculs norvégien (Norsk Regnesentral)
– http://heim.ifi.uio.no/~olejohan/
10/82
Aparté
Kristen Nygaard– 27 aout 1926 – 19 aout 2002– Norvégien– Père de Simula et de la PPO– Récipiendaire
• ACM A.M. Turing Award• IEEE John von Neumann Medal
– Développe l’idée de la PPO dans les années 1950 au Centre de calculs norvégien (Norsk Regnesentral)
– http://en.wikipedia.org/wiki/Kristen_Nygaard
11/82
Qu’est-ce la programmation par objets ?– Une façon de penser
• Objets, classes, hiérarchies
– Des mécanismes de soutient de cette pensée• Classes, interfaces, encapsulation, polymorphisme
– Une façon de• Rendre le code plus proche de sa conception• Améliorer la modularité de la conception et du code
– Avec de nombreuses implantations• Styles, bibliothèques, extension ad-hoc…
1964 1974 20041984 1994
OOPintuitive
12/82
Bonne modularité de la conception mais faible modularité de l’implantation
class Point extends Shape {
private int x = 0, y = 0;
int getX() { return x; } int getY() { return y; }
void setX(int x) { this.x = x; display.update(this); } void setY(int y) { this.y = y; display.update(this); }}
1
Display
2Point
getX()getY()setX(int)setY(int)moveBy(int, int)
Line
getP1()getP2()setP1(Point)setP2(Point)moveBy(int, int)
Shape
moveBy(int, int)
*
1964 1974 20041984 1994
MVC Observer PatternOOP
13/82
Pendant ce temps la…– Début des années 80 (peut-être même plus tôt)– D’autres travaillaient
• Structure « entrecoupantes »• Mécanismes
– Réflexion comportementale– MOP– Programmation orientée sujets
– Le terme « programmation par aspects » apparaît en 1997
1964 1974 20041984 1994
MVC Observer PatternAOP
OOP
14/82
aspect ObserverPattern { private Display Shape.display;
pointcut change(): call(void figures.Point.setX(int)) || call(void Point.setY(int)) || call(void Line.setP1(Point)) || call(void Line.setP2(Point)) || call(void Shape.moveBy(int, int)); after(Shape s) returning: change() && target(s) { s.display.refresh(); }}
ObserverPattern
1
Display
2Point
getX()getY()setX(int)setY(int)moveBy(int, int)
Line
getP1()getP2()setP1(Point)setP2(Point)moveBy(int, int)
Shape
moveBy(int, int)
*
1964 1974 20041984 1994
OOPAOP
15/82
aspect ObserverPattern { private Display Shape.display;
pointcut change(): call(void figures.Point.setX(int)) || call(void Point.setY(int)) || call(void Line.setP1(Point)) || call(void Line.setP2(Point)) || call(void Shape.moveBy(int, int)); after(Shape s) returning: change() && target(s) { s.display.refresh(); }}
ObserverPattern
1
Display
2Point
getX()getY()setX(int)setY(int)moveBy(int, int)
Line
getP1()getP2()setP1(Point)setP2(Point)moveBy(int, int)
Shape
moveBy(int, int)
*
1964 1974 20041984 1994
OOPAOP
16/82
Maintenant, est-ce que vous pourriez appeler une classe « ObserverPattern » ?
1964 1974 20041984 1994
OOPAOP
17/82
Qu’est-ce la programmation par aspects ?– Une façon de penser
• Aspects, structures entrecoupantes
– Des mécanismes de soutient de cette pensée• Points de jointure, points de coupe, « advice »
– Une façon de• Rendre le code encore plus proche de sa conception• Améliorer la modularité de la conception et du code
– Avec de nombreuses implantations• Styles, bibliothèques, extension ad-hoc…
1964 1974 20041984 1994
OOPAOP
18/82
1. Contexte
Autres aspects ?– Patron de conception– Sureté des fils d’exécution Swing– Application de politiques
• Authentification, synchronisation…
– Gestion des transactions– Débogage– Logging– …
19/82
1. Contexte
IBM rapporte– Implémentation de politiques
• 15 à 30% d’amélioration de la qualité• Gains en productivités significatifs
– Popularisation de logiciels complexes• De nouvelles opportunités d’affaires
20/82
2.Introduction aux aspects
Un premier exemple
public class ClasseDuModel { … attributs pour la logique de la classe … attributs pour l’authentification, … vérification des contrats et profilage
public void uneMethode { // authentification // vérifier les pré conditions // enregistrer l’entrée dans l’opération
… accomplir les opérations
// authentification // / vérifier les post conditions // enregistrer la sortie de l’opération } // autres méthodes}
Dans cet exemple, authentification, vérification des contrats et profilage sont croisés avec la méthode qui accomplie des fonctions reliées à la logique de la classe
21/82
A noter…
Deux problèmes sont à noter ici:
1. L’implémentation d’authentification, vérification des contrats et profilage n’est pas localisée
– Le code source est dispersé probablement dans beaucoup d’autres méthodes, classes, paquetages
2. L’implémentation de uneMethode() fait beaucoup plus que ce qu’elle devrait
– Elle contient du code source concernant plusieurs préoccupations
22/82
Symptômes de l’intrication (entrecroisement)
L’entrecroisement de concepts est relié à deux symptômes dans le développement logiciel:– Dispersion de code source (code scattering):
implémentation de concepts qui ne sont pas bien modulaires et qui sont dispersés dans le système.
– Croisement de code source (code tangling): un module peut contenir des parties de code concernant plusieurs concepts.
Dispersion et croisement sont deux aspects différents du même problème.
23/82
D’où vient l’intrication?
Il n’existe pas nécessairement une correspondance un-à-un du domaine du problème au domaine de la solution
L’espace des requis est multidimensionnel alors que l’espace de l’implémentation est unidimensionnel (en programmation orientée objets chaque classe doit avoir une seule responsabilité)
R1
R2
R3
R4
C1
C2
C3
dispersion croisement
ImplementationRequis
C4
24/82
Entrecroisement des aspects technique -nous aimerions que le diagramme se transforme…
Composant Composant Composant
25/82
…en celui-ci!
Composant Composant ComposantAspects
Nous avons besoin d’un nouveau module pour pouvoir résoudre le problème d’entrecroisement.
26/82
Principes de la POA
“AOP can be understood as the desire to make quantified statements about the behavior of programs, and to have these quantifications hold over programs written by oblivious programmers. »
Robert E. Filman and Daniel P. Friedman
Deux concepts– Quantification– Obliviousness
27/82
Principes de la POA: 1. « Quantification »
“Dans programme P, quand condition C est évaluée à vrai, exécute action A.”
C1 C2 C3
quand exécution atteintce point…
…ou ce point… …exécute ce code!
28/82
Les points dans C2 et C3 ne sont pas choisis au hasard; ils doivent être bien définis
Un point d’insertion ou de jonction (joinpoint) est un point dans le programme bien défini.– Exemple: appel/exécution d’une méthode.
C1 C2 C3A
29/82
Composant, aspects et points d’insertion
Les points d’insertion sont les endroits où les aspects interagissent avec le reste du système.
Source: [Bardou, ’98]
30/82
Principes de la POA: 2. « Obliviousness »
A noter que ni C2 ni C3 font des appels de A ! Même si les composants C2 et C3 ont été enrichis avec le
comportement fourni par l’aspect A, ils ne sont pas au courant qu’un tel enrichissement existe – ils n’ont subit aucune modification pour s’adapter à cet enrichissement.
Différence avec les appels de méthodes usuels.
C1 C2 C3A
31/82
Implémenter un programme orienté aspects
Deux étapes:
1. Décomposition: Identifier et implémenter les fonctionnalités de base (classes) et les concepts entrecroisés (aspects)
– Exemples d’aspects: authentification, vérification de contrats, profilage, sauvegarde de données.
2. Définir les règles d’interaction entre les fonctionnalités de base et les concepts entrecroisés
32/82
Finalement…public class BusinessLogic { … data members for business logic public void someOperation { … perform core operation} // more operations similar to the above}
public aspect Authenticator { … data members for authentication public void authenticate() {…}}
public aspect Logger { … data members for logging public void log() {…}}
public aspect ContractChecker { … data members for contract checking public boolean precondition() {…} public boolean postcondition(){..}}
Compilateur
33/82
Plus précisément…
Tissage d’aspects– À la compilation
• Comparer avec une compilation « traditionnelle »
34/82
Avantages de la POA
En comparaison avec la programmation orientée objets:– Une séparation nette des préoccupations – espace
bidimensionnel du domaine de l’implémentation• Code source moins dispersé et moins croisé
– Meilleure modularité: il est plus facile de analyser, déboguer, changer et réutiliser les modules
– Une maintenance plus facile
La POA ne se limite pas à la POO.• AspectL• Aspect-C
35/82
AspectJ – POA pour Java
AspectJ est une extension à Java qui fournit les moyens pour faire de la POA
AspectJ est un sur-ensemble de Java.– Chaque programme valide de Java est aussi un
programme valide d’AspectJ
36/82
public class Buffer { private String[] BUFFER; int putPtr; // keeps track of puts int getPtr; // keeps track of gets int counter; // holds number of items int capacity; Buffer (int capacity) {…} public boolean isEmpty() {…} public boolean isFull() {…} public void put (String s) {…} public String get() {…} }}
Exemple: Mémoire tampon limitée
La classe Buffer contient deux types de méthodes:– Ceux qui modifient son
état: put(), get()– Ceux qui le consultent
seulement: isFull(), isEmpty()
37/82
Comportement de la classe Buffer
public class Buffer { …public void put (String s) { if (isFull()) System.out.println("ERROR: Buffer full"); else { BUFFER[putPtr++] = s; counter++; }}
public String get() { if (isEmpty()) return "ERROR: Buffer empty"; else { counter--; return BUFFER[getPtr++]; }}
}
38/82
AspectJ language concepts
Point de jonction (joinpoint): un point bien défini dans l’exécution d’un programme– Exemple: appel de la méthode get() de la classe Buffer
Point d’action (pointcut): Un ensemble de points de jonctions.– Exemple: l’exécution de toutes les méthodes modifiant
l’état de la classe Buffer
Greffon (advice): Un block qui spécifie le code à exécuter quand un point d’action a été atteint– Exemple: avant l’appel de la méthode get(), affiche un
certain message
39/82
Exemple: Profilage
But: afficher un message avant chaque appel de la méthode put() et de la méthode get() de la classe Buffer
Comment: Définir un point de jonction. Le point de jonction suivant se réfère à une méthode publique dont le type de retour est vide, dont le nom est « put » et qui prend une chaîne de caractères en paramètre:
call(public void Buffer.put(String))
Ce point de jonction représente le moment d’exécution après l’évaluations des paramètres mais avant que la méthode soit appelée
40/82
Identifier des points de jonction
Le point de jonction suivant se réfère à chaque appel de la méthode « get » sans paramètres et dont le type de retour est une chaîne de caractères et dont la visibilité est « public »
call (public String Buffer.get())
41/82
Définir un point d’action
Le point d’action suivant définit un point d’action dont le nom est « mutators » et qui sera activé si l’un des points de jonction précédemment définis est satisfait
pointcut mutators(): call(public void Buffer.put(String)) || call (public String Buffer.get());
42/82
Définir un greffon
Le greffon définit le code à exécuter quand un point d’action est activé.
Un greffon est donc défini par rapport à un point d’action
Le type de greffon doit aussi être spécifié. Dans ce cas, le greffon sera exécuter avant ce qui est référé par le point d’action
before(): mutators() { System.out.println("------ Mutator method called.");}
43/82
Il existe trois façons d’associer un greffon à un point d’action:– before: s’exécute juste avant le point d’action– after: s’exécute juste après le point d’action– around: s’exécute à la place du code qui est
référé par le point d’action. • Donne la possibilité d’exécuter le code défini par le
point d’action en plus en appelant proceed()
44/82
Définir un aspect
Un aspect est un module Il définit ses points d’action et ses greffons
public aspect Tracer { pointcut mutators(): call(public void Buffer.put(String)) || call (public String Buffer.get()); before(): mutators() { System.out.println("------ Mutator method called."); }}
45/82
Profilage ?
public class BufferDemo { public static void main(String[] args) { Buffer buffer = new Buffer(10); buffer.put("Hello"); buffer.put("there"); System.out.println(buffer.get()); System.out.println(buffer.get()); }}
public aspect Tracer { pointcut mutators(): call(public void Buffer.put(String)) || call (public String Buffer.get()); before(): mutators() { System.out.println("------ Mutator method called."); }}
Quelle serait la sortie du programme ???
46/82
Profilage
public class BufferDemo { public static void main(String[] args) { Buffer buffer = new Buffer(10); buffer.put("Hello"); buffer.put("there"); System.out.println(buffer.get()); System.out.println(buffer.get()); }}
public aspect Tracer { pointcut mutators(): call(public void Buffer.put(String)) || call (public String Buffer.get()); before(): mutators() { System.out.println("------ Mutator method called."); }}
------ Mutator method called.------ Mutator method called.------ Mutator method called.Hello------ Mutator method called.there
47/82
Types de points de jonction
1. Appels de méthodes et constructeurs2. Exécution de méthodes et constructeurs3. Accès à un attribut4. Gestion des exceptions5. Initialisation d’une classe6. Structure lexicale7. Flux de control8. Objets visés et arguments9. Tests de conditions
48/82
Appels de méthodes et constructeurs
Appel de toute méthode dont le nom commence avec “myMethod” de MyClass.
call (* MyClass.myMethod*(..))
Appel à myMethod() de MyClass prenant tout type d’arguments, retournant n’importe quel type.
call (* MyClass.myMethod(..))
Appel à myMethod() de MyClass prenant tout type d’arguments, dont le type de retour est void, peu importe la visibilité
call (void MyClass.myMethod(..))
Appel à myMethod() de MyClass prenant un argument de type String, retournant void, avec visibilité public
call (public void MyClass.myMethod(String))
49/82
Appel au constructeur de MyClass avec n’importe quels types d’arguments
call (MyClass.new(..))
Appel au constructeur de MyClass qui ne prend pas d’arguments
call (MyClass.new())
Appel à myMethod() de n’importe quelle classe dans le paquetage default
call (* *.myMethod(..))
Appel à toute méthode dont le nom commence avec “myMethod” de MyClass et dont le premier argument est de type String
call (* MyClass.myMethod*(String,..))
50/82
Appel à toute méthode public dans chaque classe de n’importe quel paquetage dont le paquetage racine est com.company
call (public * com.mycompany..(.*(..)))
Appel au constructeur de MyClass ou un de ses enfants, dont les types d’arguments ne sont pas importants
call (MyClass+.new(..))
51/82
Exécution de méthodes et constructeurs
Exécution de toute méthode dont le nom commence avec “myMethod” de MyClass.
execution(* MyClass.myMethod*(..))
Exécution de “myMethod” de MyClass prenant n’importe quels types d’argu-ments et peu importe le type de retour
execution(* MyClass.myMethod(..))
Exécution de myMethod() de MyClass prenant n’importe quels types d’arguments, retournant void
execution(void MyClass.myMethod(..))
Exécution de myMethod() de MyClass prenant un argument de type String, retournant void, et avec visibilité public
execution (public void MyClass.myMethod(String))
Exécution de toute méthode dont le nom commence avec ‘myMethod” de MyClass et dont le premier argument est de type String
execution(* MyClass.myMethod* (String, ..))
52/82
Exécution de tout constructeur de MyClass ou une de ses sous classes
execution(* MyClass+.new(..))
Exécution de tout constructeur de MyClass
execution(MyClass.new(..))
Exécution du constructeur par défaut de MyClass.
execution(MyClass.new())
Exécution de myMethod() dans toute classe dans le paquetage default
execution (* *.myMethod(..))
Toute méthode publique de toute classe avec paquetage racine com.company
execution(public * com.mycompany..*.*(..))
53/82
Accès à un attribut
Exécution de l’écriture dans l’attribut x de type int de classe MyClass.
set (int MyClass.x)
Exécution de lecture de l’attribut out de type PrintStream de classe System
get(PrintStream System.out)
54/82
Gestion des exceptions
Exécution d’un block catch d’une exception dont le nom du type commence avec “CreditCard”.
handler (CreditCard*)
Exécution d’un block catch d’exception de type/ sous type de IOException
handler (IOException)
Exécution d’un block catch d’une exception de type RemoteException
handler (RemoteException)
55/82
Initialisation d’une classe
Exécution d’un block statique de MyClass ou une de ses sous classes.
staticinitialization(MyClass+)
Exécution d’un block statique de MyClass
staticinitialization(MyClass)
56/82
Structure lexicale
Tout point de jonction dans la définition de toute méthode myMethod() de MyClass
withincode(* MyClass.myMethod(..))
Tout point de jonction dans la définition de classes dont les noms commencent avec “MyClass”
within(MyClass*)
Tout point de jonction dans la définition de MyClass
within(MyClass)
57/82
Flux de control
Tout point de jonction dans le flux de control de l’appel à la méthode myMethod() de MyClass excluant l’appel à la méthode spécifiée
cflowbelow(call (* MyClass.myMethod(..))
Tout point de jonction dans le flux de control de l’appel à la méthode myMethod() de MyClass incluant l’appel à la méthode spécifiée
cflow(call (* MyClass.myMethod(..))
58/82
Objets visés et arguments
Tout point de jonction où le type d’argument ou l’exception que l’on veut gérer est RemoteException
args(RemoteException)
Tout point de jonction où le premier argument est de type String et le dernier est de type int.
args(String, …, int)
Tout pont de jonction où l’objet sur lequel la méthode est appelé est de type MyClass.
target(MyClass)
Tout point de jonction où this instanceof JComponent est vrai
this(JComponent)
59/82
Tests de conditions
Tout point de jonction où EventQueue.isDispatchedThread() est évalué à vrai
if (EventQueue.isDispatchedThread())
60/82
Exemple: Vérification de contrats de la classe Buffer – nouvelle class BBuffer
public class BBuffer { private String[] BUFFER; private int putPtr; // keeps track of puts private int getPtr; // keeps track of gets protected int capacity;
BBuffer (int capacity) { BUFFER = new String[capacity]; this.capacity = capacity; }
public void put (String s) {BUFFER[putPtr++] = s;}
public String get() {return BUFFER[getPtr++];}
}
61/82
Introduire des attributs à BBuffer et déclarer des points d’action
private int BBuffer.counter = 0;
private boolean BBuffer.isEmpty() { return (this.counter==0);}
private boolean BBuffer.isFull() { return (this.counter == this.capacity);}
pointcut puts(BBuffer object): execution (* BBuffer.put(String)) && this(object);
pointcut gets(BBuffer object):execution (* BBuffer.get()) && this(object);
62/82
around() greffon pour la méthode put()
void around (BBuffer object): puts(object) { if (object.isFull()) System.out.println("ERROR: Buffer full"); else { // go ahead with the method call. // proceed() takes the same number and types of arguments // as the around() advice. proceed(object); object.counter++; }}
63/82
around() greffon pour la méthode get()
String around(BBuffer object) : gets(object){ if (object.isEmpty()) return "ERROR: Buffer empty"; else { object.counter--; return proceed(object); }}
64/82
L’aspect Synchronizationpublic aspect Synchronization {
private int BBuffer.counter = 0;private boolean BBuffer.isEmpty() {return (this.counter==0);}private boolean BBuffer.isFull() {return (this.counter == this.capacity);}pointcut puts(BBuffer object): execution (* BBuffer.put(String)) && this(object);pointcut gets(BBuffer object): execution (* BBuffer.get()) && this(object);void around (BBuffer object): puts(object) {
if (object.isFull()) System.out.println("ERROR: Buffer full");else {
// go ahead with the method call.// proceed() takes the same number and types of arguments// as the around() advice.proceed(object);object.counter++;
}}String around(BBuffer object) : gets(object){
if (object.isEmpty()) return "ERROR: Buffer empty";else {
object.counter--;return proceed(object); }}}
65/82
Exécution du programme
public class BufferDemo { public static void main(String[] args) { BBuffer buffer = new BBuffer(2); buffer.put("Item 1 "); buffer.put("Item 2 "); buffer.put("Item 3 "); buffer.put("Item 4 "); System.out.println(buffer.get()); System.out.println(buffer.get()); System.out.println(buffer.get()); System.out.println(buffer.get()); }}
ERROR: Buffer fullERROR: Buffer fullItem 1 Item 2 ERROR: Buffer emptyERROR: Buffer empty
66/82
3. Conception par aspects
Principes– Martin, Newkirk, and Koss ; Agile Software
Development, Principles, Patterns, and Practices ; Prentice Hall, 2003
– Wampler ; Aspect-Oriented Design Principles: Lessons from Object-Oriented Design ; AOSD, 2007
Une conception par aspects doit préserver les principes clés du paradigme orienté objet.
67/82
3. Conception par aspects
Single Responsibility Principle (SRP)– A class should have only one reason to change
Open-Closed Principle (OCP)– Software entities (classes, aspects, modules,
functions, etc.) should be open for extension, but closed for modification
68/82
3. Conception par aspects
Interface Segregation Principle (ISP)– Clients should not be forced to depend upon
methods that they do not use. Interfaces belong to clients, not to hierarchies
Liskov Substitution Principle (LSP)– Subtypes must be substitutable for their base
types Les aspects doivent préserver le sous-
typage ou ils « cassent » le programme
69/82
3. Conception par aspects
Dependency Inversion Principle (DIP)– High-level modules should not depend on low-
level modules. Both should depend on abstractions
– Abstractions should not depend upon details. Details should depend upon abstractions
70/82
3. Conception par aspects
Dependency Inversion Principle (DIP)
71/82
3. Conception par aspects
Common Closure Principle (CCP)– The classes in a package should be closed
together against the same kinds of changes. A change that affects a closed package affects all the classes in that package and no other packages
72/82
3. Conception par aspects
Stable Dependencies Principle (SDP)– Depend in the direction of stability
Stable Abstractions Principle (SAP)– A package should be as abstract as it is stable
73/82
3. Conception par aspects
Updated Open-Closed Principle (OCP’)– Software entities (classes, aspects, modules,
functions, etc.) should be open for extension, but closed for source and contract modification
Updated Liskov Substitution Principle (LSP')– Subtypes must be substitutable for their base
types. Aspects plus base types must be substitutable for the base types.
74/82
3. Conception par aspects
Advice Substitution Principle (ASP)– Before advice must support the same or weaker
preconditions of the join point it advices. – After advice must support the same or stronger
postconditions of the join point it advices. – Around advice must support the same or weaker
preconditions of the join point it advices and the same or stronger postconditions of the join point
– All advice must support the invariants of the join point
75/82
3. Conception par aspects
Introduction Substitution Principle (ISP)– An Introduction must conform to the contract of
the advised module and, if called by advice, it must conform to the ASP of the advice
76/82
3. Conception par aspects
Pointcut Inversion Principle (PIP)– Pointcuts should not depend on concrete details;
they should depend on abstractions
Pointcut Scope Principle (PSP)– The more pervasive the scope of a pointcut, the
more abstract it should be
77/82
3. Conception par aspects
Réécriture des patrons de conception sous forme d’aspects– Hannemann and Kiczales ; Design Pattern
Implementation in Java and AspectJ ; OOPSLA, 2002
– 17 patrons sur 23 sont modularisés
78/82
3. Conception par aspects
79/82
4. Avantages et inconvénients
Problèmes– Bonne et mauvaise utilisation
• Peut être sur-utilisée ou mal utilisée• De nouvelles connaissances sont nécessaires
– Très « tendance », mais peu de cours• Chaque nouvelle technologie a ses zélotes et ses critiques• De vieilles leçons sont toujours d’actualités
– Outils• Qualité et soutient
– Enseignement, entrainement– Valeur d’affaire ?
80/82
Avantages et inconvénients
Problèmes : mauvaise utilisation– Mécanismes peuvent être mal utilisés
• Trop ou mauvaises procedures• Trop ou mauvaises classes• Trop ou mauvaises surcharge• Trop ou mauvais aspects, advice, introductions…
– Déjà une bonne leçon • Règle des 15%
– Encore à apprendre• Interaction avec JSR-175 (metadata)• Passage à l’échelle
81/82
Références
http://andrewclement.blogspot.com/2009/02/load-time-weaving-basics.html
http://www.eclipse.org/aspectj/sample-code.html
http://www.cse.wustl.edu/~mdeters/doc/slides/aspectjtutorial.pdf
http://www.eclipse.org/aspectj/doc/released/progguide/index.html
82/82
Références
http://www.eclipse.org/aspectj/doc/released/progguide/index.html
http://aosd.net/2007/program/industry/I6-AspectDesignPrinciples.pdf
http://www.cs.ubc.ca/labs/spl/papers/2002/oopsla02-patterns.pdf