82
Foutse Khomh © Guéhéneuc, 2009; Arnaoudova, 2010; Khomh, 2010 Dé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

LOG4430 : Architecture logicielle et conception avancée

  • 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

Page 1: LOG4430 : Architecture logicielle et conception avancée

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

Page 2: LOG4430 : Architecture logicielle et conception avancée

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

Page 3: LOG4430 : Architecture logicielle et conception avancée

3/82

1. Contexte

Pensez à la source de tous les maux en génie logiciel ?

Page 4: LOG4430 : Architecture logicielle et conception avancée

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

Page 5: LOG4430 : Architecture logicielle et conception avancée

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

Page 6: LOG4430 : Architecture logicielle et conception avancée

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

Page 7: LOG4430 : Architecture logicielle et conception avancée

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

Page 8: LOG4430 : Architecture logicielle et conception avancée

8/82

Aparté

Page 9: LOG4430 : Architecture logicielle et conception avancée

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/

Page 10: LOG4430 : Architecture logicielle et conception avancée

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

Page 11: LOG4430 : Architecture logicielle et conception avancée

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

Page 12: LOG4430 : Architecture logicielle et conception avancée

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

Page 13: LOG4430 : Architecture logicielle et conception avancée

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

Page 14: LOG4430 : Architecture logicielle et conception avancée

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

Page 15: LOG4430 : Architecture logicielle et conception avancée

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

Page 16: LOG4430 : Architecture logicielle et conception avancée

16/82

Maintenant, est-ce que vous pourriez appeler une classe « ObserverPattern » ?

1964 1974 20041984 1994

OOPAOP

Page 17: LOG4430 : Architecture logicielle et conception avancée

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

Page 18: LOG4430 : Architecture logicielle et conception avancée

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– …

Page 19: LOG4430 : Architecture logicielle et conception avancée

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

Page 20: LOG4430 : Architecture logicielle et conception avancée

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

Page 21: LOG4430 : Architecture logicielle et conception avancée

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

Page 22: LOG4430 : Architecture logicielle et conception avancée

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.

Page 23: LOG4430 : Architecture logicielle et conception avancée

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

Page 24: LOG4430 : Architecture logicielle et conception avancée

24/82

Entrecroisement des aspects technique -nous aimerions que le diagramme se transforme…

Composant Composant Composant

Page 25: LOG4430 : Architecture logicielle et conception avancée

25/82

…en celui-ci!

Composant Composant ComposantAspects

Nous avons besoin d’un nouveau module pour pouvoir résoudre le problème d’entrecroisement.

Page 26: LOG4430 : Architecture logicielle et conception avancée

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

Page 27: LOG4430 : Architecture logicielle et conception avancée

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!

Page 28: LOG4430 : Architecture logicielle et conception avancée

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

Page 29: LOG4430 : Architecture logicielle et conception avancée

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]

Page 30: LOG4430 : Architecture logicielle et conception avancée

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

Page 31: LOG4430 : Architecture logicielle et conception avancée

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

Page 32: LOG4430 : Architecture logicielle et conception avancée

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

Page 33: LOG4430 : Architecture logicielle et conception avancée

33/82

Plus précisément…

Tissage d’aspects– À la compilation

• Comparer avec une compilation « traditionnelle »

Page 34: LOG4430 : Architecture logicielle et conception avancée

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

Page 35: LOG4430 : Architecture logicielle et conception avancée

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

Page 36: LOG4430 : Architecture logicielle et conception avancée

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()

Page 37: LOG4430 : Architecture logicielle et conception avancée

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++]; }}

}

Page 38: LOG4430 : Architecture logicielle et conception avancée

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

Page 39: LOG4430 : Architecture logicielle et conception avancée

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

Page 40: LOG4430 : Architecture logicielle et conception avancé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())

Page 41: LOG4430 : Architecture logicielle et conception avancée

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());

Page 42: LOG4430 : Architecture logicielle et conception avancée

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.");}

Page 43: LOG4430 : Architecture logicielle et conception avancée

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()

Page 44: LOG4430 : Architecture logicielle et conception avancée

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."); }}

Page 45: LOG4430 : Architecture logicielle et conception avancée

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 ???

Page 46: LOG4430 : Architecture logicielle et conception avancée

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

Page 47: LOG4430 : Architecture logicielle et conception avancée

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

Page 48: LOG4430 : Architecture logicielle et conception avancée

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))

Page 49: LOG4430 : Architecture logicielle et conception avancée

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,..))

Page 50: LOG4430 : Architecture logicielle et conception avancée

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(..))

Page 51: LOG4430 : Architecture logicielle et conception avancée

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, ..))

Page 52: LOG4430 : Architecture logicielle et conception avancée

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..*.*(..))

Page 53: LOG4430 : Architecture logicielle et conception avancée

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)

Page 54: LOG4430 : Architecture logicielle et conception avancée

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)

Page 55: LOG4430 : Architecture logicielle et conception avancée

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)

Page 56: LOG4430 : Architecture logicielle et conception avancée

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)

Page 57: LOG4430 : Architecture logicielle et conception avancée

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(..))

Page 58: LOG4430 : Architecture logicielle et conception avancée

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)

Page 59: LOG4430 : Architecture logicielle et conception avancée

59/82

Tests de conditions

Tout point de jonction où EventQueue.isDispatchedThread() est évalué à vrai

if (EventQueue.isDispatchedThread())

Page 60: LOG4430 : Architecture logicielle et conception avancée

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++];}

}

Page 61: LOG4430 : Architecture logicielle et conception avancée

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);

Page 62: LOG4430 : Architecture logicielle et conception avancée

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++; }}

Page 63: LOG4430 : Architecture logicielle et conception avancée

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); }}

Page 64: LOG4430 : Architecture logicielle et conception avancée

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); }}}

Page 65: LOG4430 : Architecture logicielle et conception avancée

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

Page 66: LOG4430 : Architecture logicielle et conception avancée

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.

Page 67: LOG4430 : Architecture logicielle et conception avancée

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

Page 68: LOG4430 : Architecture logicielle et conception avancée

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

Page 69: LOG4430 : Architecture logicielle et conception avancée

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

Page 70: LOG4430 : Architecture logicielle et conception avancée

70/82

3. Conception par aspects

Dependency Inversion Principle (DIP)

Page 71: LOG4430 : Architecture logicielle et conception avancée

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

Page 72: LOG4430 : Architecture logicielle et conception avancée

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

Page 73: LOG4430 : Architecture logicielle et conception avancée

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.

Page 74: LOG4430 : Architecture logicielle et conception avancée

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

Page 75: LOG4430 : Architecture logicielle et conception avancée

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

Page 76: LOG4430 : Architecture logicielle et conception avancée

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

Page 77: LOG4430 : Architecture logicielle et conception avancée

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

Page 78: LOG4430 : Architecture logicielle et conception avancée

78/82

3. Conception par aspects

Page 79: LOG4430 : Architecture logicielle et conception avancée

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 ?

Page 80: LOG4430 : Architecture logicielle et conception avancée

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

Page 81: LOG4430 : Architecture logicielle et conception avancée

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

Page 82: LOG4430 : Architecture logicielle et conception avancée

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