Vous êtes sur la page 1sur 21

CHAPITRE 1

Le paradigme aspect
1.1 INTRODUCTION
La programmation orientée aspect (POA) est un nouveau paradigme de programmation
qui trouve ses racines en 1996, suite aux travaux de Gregor Kiczales et de son équipe au
Centre de Recherche Xerox à Palo Alto. La POA est donc une technologie relativement jeune,
puisque les premiers outils destinés à son utilisation ne sont apparus qu’à la fin des années 90.
Cependant, l’adoption de la POA est plutôt rapide puisqu’elle semble déjà bien diffusée
aujourd’hui. A titre comparatif, le langage Simula, pionnier de la programmation orienté
objet, est apparu en 1967, alors que la POO n’a réellement émergé qu’au cours des années 80
avec C++.

En effet, aidée par une compatibilité entre ses concepts sous-jacents et ceux existants, la
POA peut être intégrée à moindre coût par les entreprises en étendant leurs outils. Par
exemple, la POA pour Java est intégrée dans Eclipse via un plugin qui permet l’utilisation du
langage AspectJ. Ce langage, dont les premières versions furent disponibles en 1998, étend en
fait le langage Java en introduisant de nouveaux mots-clés permettant de programmer des
aspects. Mais AspectJ n’est pas l’unique langage orienté aspect. Même si celui-ci reste le plus
utilisé, d’autres outils existent. On peut notamment citer JAC, JBoss AOP et AspectWerkz
rien que pour le langage Java, mais il existe également des outils pour les langages C, C++,
C# ou Smalltalk. La compatibilité entre les concepts utilisés par la POA et les outils existants
est due au fait que la POA ne remet pas en cause les autres paradigmes de programmation
(comme l’approche procédurale ou objet). Au contraire, elle les étend en proposant des
mécanismes complémentaires afin d’améliorer la modularité d’une application (et donc
faciliter la réutilisation et la maintenance.

5
CHAPITRE 1 – LE PARADIGME ASPECT 6

1.2 Les approches de programmation

1.2.1 Méthodes fonctionnelles ou structurées


Les méthodes fonctionnelles (également qualifiées de méthodes structurées) trouvent leur
origine dans les langages procéduraux. Elles mettent en évidence les fonctions à assurer et
proposent une approche hiérarchique descendante et modulaire.

Figure 1.1 - Représentation graphique d'une approche fonctionnelle

Ces méthodes utilisent intensivement les raffinements successifs. Le plus haut niveau
représente l’ensemble du problème. Chaque niveau est ensuite décomposé en respectant les
entrées/sorties du niveau supérieur. La décomposition se poursuit jusqu’à arriver à des
composants maîtrisables (figure 1.1).

L’approche fonctionnelle dissocie le problème de la représentation des données du


problème, du traitement de ces données. Sur la figure 1.1, les données du problème sont
représentées sur la gauche. Des flèches transversales matérialisent la manipulation de ces
données par des sous-fonctions. Cet accès peut-être direct (c’est parfois le cas quand les
données sont regroupées dans une base de données), ou peut être réalisé par le passage de
paramètre depuis le programme principal.

6
CHAPITRE 1 – LE PARADIGME ASPECT 7

L’approche structurée privilégie la fonction comme moyen d’organisation du logiciel,


l’évolution des besoins entraîne souvent une dégénérescence, ou une profonde remise en
question, de la topologie typique de la figure 1.1 car la décomposition des unités de traitement
(du programme principal aux sous-fonctions) est directement dictée par ces besoins. D’autre
part, une modification des données entraîne généralement une modification d’un nombre
important de fonctions éparpillées et difficiles à identifier dans la hiérarchie de cette
décomposition.

En résumé, l’architecture du système est dictée par la réponse au problème (i.e. la fonction
du système).

1.2.2 L’approche orientée objet

Dès les années 1980, l'approche objet s'est généralisée dans les tâches d'analyse et de
conception, car elle permet d'affronter la complexité croissante des grands systèmes,
beaucoup plus facilement que ne l'autorise l'approche procédurale. La Conception Orientée
Objet (COO) est la méthode qui conduit à des architectures logicielles fondées sur les objets
du système, plutôt que sur la fonction qu’il est censé réaliser. Les techniques orientées objet
sont mieux adaptées à la modélisation que la décomposition fonctionnelle, qui tend à produire
des modèles plus fragiles aux évolutions et par conséquent plus difficiles à maintenir. Un
système, et surtout, dans le cas des systèmes complexes, peut se modéliser comme une
collection d'éléments (les objets) capables d'interagir pour travailler ensemble.

Un objet est un élément de granularité moyenne, plus petit qu'un système, qu'un sous-
système ou qu'un module, mais plus grand qu'une donnée élémentaire. La taille d'un objet doit
correspondre à une granularité facile à gérer et garantissant la cohésion du contenu de l'objet.

1.2.2.1 Notion d'objet

Un objet est une entité logicielle ayant une identité capable de sauvegarder un état c'est-à-
dire un ensemble d’information dans des variables internes, répondant à des messages précis
en déclenchant des activations internes appropriés qui changent l’état de l’objet. Ces opération

7
CHAPITRE 1 – LE PARADIGME ASPECT 8

sont appelées méthodes. Ce sont des fonctions liées à des objets et qui précisent le
comportement de ces objets.

1.2.2.2 Notion de classe

Une classe est un type de données abstrait qui précise des caractéristiques (attributs et
méthodes) communes à toute une famille d’objets et qui permet de créer (instancier) des
objets possédant ces caractéristiques.

1.2.2.3 Héritage, Spécialisation, Généralisation et Polymorphisme

L’héritage est un mécanisme de transmission des caractéristiques d’une classe (ses


attributs et méthodes) vers une sous-classe. Une classe peut être spécialisée en d’autres
classes, afin d’y ajouter des caractéristiques spécifiques ou d’en adapter certaines. Plusieurs
classes peuvent être généralisées en une classe qui les factorise, afin de regrouper les
caractéristiques communes d’un ensemble de classes.

Ainsi, la spécialisation et la généralisation permettent de construire des hiérarchies de


classes. L’héritage peut être simple ou multiple. L’héritage évite la duplication et encourage la
réutilisation.

Le polymorphisme représente la faculté d’une méthode à pouvoir s’appliquer à des objets


de classes différentes. Le polymorphisme augmente la généricité, et donc la qualité, du code.

1.2.2.4 Agrégation

Il s’agit d’une relation entre deux classes, spécifiant que les objets d’une classe sont des
composants de l’autre classe. Une relation d’agrégation permet donc de définir des objets
composés d’autres objets. L’agrégation permet donc d’assembler des objets de base, afin de
construire des objets plus complexes.

En approche objet, l’évolution des besoins aura le plus souvent tendance à se présenter
comme un changement de l’interaction des objets. S’il faut apporter une modification aux

8
CHAPITRE 1 – LE PARADIGME ASPECT 9

données, seul l’objet incriminé (encapsulant cette donnée) sera modifié. Toutes les fonctions à
modifier sont bien identifiées : elles se trouvent dans ce même objet : ce sont ses méthodes

Ainsi la technologie objet est la conséquence ultime de la modularisation du logiciel,


démarche qui vise à maîtriser sa production et son évolution. Mais malgré cette continuité
logique les langages objet ont apporté en pratique un profond changement dans l’art de la
programmation : ils impliquent en effet un changement de l’attitude mentale du programmeur.

1.2.3 Les limites de la programmation orienté objet :

La programmation orientée objet (POO) offre plusieurs avantages grâce aux différents
atouts qu'elle présente en terme d'héritage, polymorphisme, etc. Cependant, ce paradigme de
programmation n'est pas dépourvu de défauts. En particulier, la réutilisation n'est pas toujours
aisée. C'est notamment le cas pour les applications qui sont sujets à des changements
fréquents et qui nécessitent, en plus de la définition des objets métiers, la prise en compte des
différentes propriétés transversales, telles que la synchronisation des accès concurrents et la
sécurité. De telles propriétés affectent l'exécution de différents objets. De ce fait, leurs
définitions se trouvent mélangées avec le code métier et dispersées entre les différentes
classes.

1.2.4 Problèmes des différentes approches de programmation

Tout système informatique peut être vu comme un ensemble de préoccupations. Une


préoccupation est en fait un but particulier, une problématique d'un logiciel qui correspond à
une de ses exigences. Dans la plupart des implémentations actuelles, on procède à ce qu'on
appelle la découpe fonctionnelle du système, le système est divisé en modules, représentant
chacun une fonctionnalité particulière.

9
CHAPITRE 1 – LE PARADIGME ASPECT 10

Figure 1.2 - Les exigences non-fonctionnelles traversant la modularisation fonctionnelle du


système

Les exigences non-fonctionnelles sont difficilement prises en compte dans une telle
découpe et on se contente donc de les intégrer dans les différents modules fonctionnels. La
figure 1.2 montre un exemple d'une application composée de 3 modules fonctionnels dans
lesquels on a du y insérer l'implémentation d'exigences de performance, de journalisation
(enregistrement d'informations dans un fichier journal) et de synchronisation.

Les exigences non-fonctionnelles qui traversent la modularisation fonctionnelle du


système posent deux problèmes:

1.2.4.1 La dispersion du code

Considérons un langage orienté objet, l'unité fonctionnelle est le package et si nous


raffinons encore la découpe, cette unité est la classe. Il n'est pas rare de voir des méthodes
traitant d'une exigence non-fonctionnelle se disperser dans l'implémentation des différentes
classes composant le coeur fonctionnel du système. Par exemple, dans un système de gestion
de base de données il se peut que la performance, la journalisation et la synchronisation
concernent toutes les classes accédant à la base de données. On voit donc que ces aspects
seront implémentés dans plusieurs modules sans être bien circonscrits. Il s'agit très souvent de
portions de code très similaires à ajouter un peu partout dans les modules concernés.

10
CHAPITRE 1 – LE PARADIGME ASPECT 11

1.2.4.2 L’enchevêtrement du code

Ce problème découle directement du constat précédent: certaines préoccupations non-


fonctionnelles viennent recouper l'implémentation des préoccupations fonctionnelles. Il en
résulte la présence d'éléments de plusieurs problématiques dans l'implémentation d'un seul et
même module. Reprenant l'exemple précédent, le code qui a trait à l'aspect performance,
journalisation et synchronisation viendra s'enchevêtrer dans les classes d'accès à la base de
données.

Ces 2 problèmes entraînent des conséquences négatives sur le développement d'un


logiciel:

− Traçage difficile: les différentes préoccupations d'un logiciel deviennent difficilement


identifiables dans l'implémentation. Il en résulte une correspondance assez obscure entre les
exigences et leurs implémentations.

− Diminution de la productivité: la prise en considération de plusieurs exigences au sein


d'un même module empêche le programmeur de se focaliser uniquement sur son but premier.
Le danger d'accorder trop ou pas assez d'importance aux aspects accessoires d'un module en
découle directement.

− Diminution de la réutilisation du code: dans les conditions actuelles, un module


implémente de multiples exigences. D'autres systèmes nécessitant des fonctionnalités
similaires pourraient ne pas pouvoir réutiliser le module tel quel, entraînant de nouveau une
diminution de la productivité à moyen terme.

− Diminution de la qualité du code: les programmeurs ne peuvent pas se concentrer sur


toutes les contraintes à la fois. L'implémentation disparate de certaines préoccupations peut
entraîner des effets de bords non-désirés, i.e. des bugs.

− Maintenance et évolutivité du code difficile: lorsque l'on veut faire évoluer le système,
on doit modifier de nombreux modules. Modifier chaque sous-système pour répercuter les
modifications souhaitées peut conduire à des incohérences.

11
CHAPITRE 1 – LE PARADIGME ASPECT 12

1.3 LA PROGRAMMATION ORIENTE ASPECT

La programmation orientée aspect (PAO) apporte une solution élégante et facile à


implémenter aux problèmes de dispersion et d'enchevêtrement du code. La PAO est une
méthode de programmation qui permet de séparer l'implémentation des exigences
fonctionnelles et non fonctionnelles. Le principe est donc de coder chaque problématique
séparément et de définir leurs règles d'intégration pour les combiner en vue de former le
système final.

Figure. 1.3 – Séparation des préoccupations d’une application

Cette nouvelle notion d’aspect, introduite par la POA, change la façon dont le design
d’une application est réalisé. Les fonctionnalités transversales sont expulsées du code métier
(voir figure 1.3). La première étape du design constitue l’identification des classes en tant que
socle de l’application. Il s’agit des données et des traitements qui sont au coeur de la
problématique de l’application et qui répondent aux besoins premiers de celle-ci.

12
CHAPITRE 1 – LE PARADIGME ASPECT 13

Figure 1.4 – Identification des aspects d’une application

Les préoccupations transversales du programme ne doivent donc pas se retrouver dans les
classes. Elles sont identifiées dans la deuxième partie du design : l’identification des aspects
(voir figure 1.4).

Les aspects identifiés peuvent être implémentés en parallèle. Ainsi, la partie sécurité d’une
application pourra, par exemple, être confiée au service approprié de l’équipe de
développement, pendant que l’aspect persistance sera implémenté par un autre service.

1.3.1 Points de jointure

Les points de jointure désignent des points précis dans l'exécution d'un programme. Il
s'agit ici de points bien précis et exploitables comme l'appel d'une méthode, l'affectation d'une
variable,... etc. Un point de jonction est un point dans l’exécution d’un programme autour
duquel un ou plusieurs aspects peuvent être ajoutés.

Un point de jonction représente un événement dans l’exécution du programme qui peut


être intercepté pour exécuter un code advice correspondant. Plusieurs types d’événements
peuvent faire figures de points de jonction.

1. Méthodes. C’est autour des méthodes que les aspects se greffent le plus souvent. Ce
n’est pas étonnant puisque les méthodes forment l’outil principal de la POO et structurent
l’exécution du programme. Les événements liés aux méthodes qui constituent des points de
jonction sont l’appel d’une méthode et l’exécution de celle-ci.

13
CHAPITRE 1 – LE PARADIGME ASPECT 14

2. Constructeurs. Les constructeurs peuvent être considérés comme des méthodes


particulières. Il s’agit de méthodes invoquées lorsqu’un objet est instancié. Comme pour les
méthodes, la POA permet d’intercepte cet événement.

3. Exceptions. Les événements de levée et de récupération d’exceptions peuvent aussi


constituer des points de jonction. Leurs utilisations sont justifiées pour un cas de gestion
centralisée d’une exception par exemple. Le code à exécuter lors de la levée de cette
exception ne sera défini qu’une seule fois dans un aspect.

4. Attributs. La lecture et la modification d’attributs constituent également des points de


jonction. On peut penser notamment à une utilisation à des fins de persistance.

1.3.2 Coupes
Points de jonction et coupes sont conceptuellement fort différents : alors qu’un point de
jonction représente un point dans l’exécution d’un programme, une coupe est un morceau de
code défini dans un aspect. C’est à elle qu’est attribué le rôle de définir la structure
transversale d’un aspect. Pour ce faire, une coupe est définie par des mots-clés identifiant des
ensembles de points de jonction. Ces ensembles sont unis dans la coupe par des opérations
ensemblistes de base (intersection, union et complémentarité).

Les mots-clés utilisés par la coupe désignent chacun un ensemble de points de jonction en
spécifiant son type (appel de méthode, lecture d’attributs, ...) et une expression qui précise le
type (la méthode α, l’attribut β, ...). Ces expressions peuvent faire usage de quantificateurs à
des fins de généralité (ex : toutes les méthodes dont le nom est μ, toutes les méthodes qui
prennent en paramètre une instance de la classe λ, tous les attributs de la classe φ,...).

Les outils existants fournissent également des mots-clés identifiant des ensembles ne
dépendant pas d’un type (ex : tous les points de jonction dans le code d’une méthode, tous les
points de jonction d’une classe, ...). Ceci permet une plus riche expressivité dans la définition
de la coupe.

14
CHAPITRE 1 – LE PARADIGME ASPECT 15

1.3.3 Codes Advices

Un aspect définit une fonctionnalité transversale. Il spécifie le caractère transversal grâce


aux coupes. La fonctionnalité est, quant à elle, spécifiée par des codes advices. Un code
advice est un bloc de code définissant le comportement d’un aspect.

Un code advice définit donc un bloc de code qui va venir se greffer sur les points de
jonction définis par la coupe à laquelle il est lié. Il existe différentes manières de greffer un
code advice sur un point de jonction. Le code advice spécifie lui-même la façon dont il
souhaite s’intégrer aux points de jonction de sa coupe.

Les trois principaux types de greffe de codes advices sont :

1. Avant les points de jonction

2. Après les points de jonction

3. Autour des points de jonction

1.3.4 Tissage d’aspects ou Weaving

Les aspects définissent des morceaux de code et les endroits de l’application où ils vont
s’appliquer. Un traitement automatique est donc nécessaire pour intégrer ces aspects dans
l’application afin d’obtenir un programme fonctionnel fusionnant classes et aspects.

Figure 1.5 – Tissage des aspects

15
CHAPITRE 1 – LE PARADIGME ASPECT 16

Cette opération, représentée sur la figure 1.5, se nomme le tissage (weaving) et est réalisée
par le tisseur d’aspects (aspect weaver ).

Le tissage peut se réaliser soit à la compilation, soit à l’exécution. Lorsqu’il est effectué a
la compilation, le tisseur d’aspects se comporte pratiquement comme un compilateur (on le
dénomme même parfois compilateur d’aspects). Il prend en entrée les classes et les aspects
pour donner en sortie une application tissée. La sortie peut être sous la forme d’exécutable, de
byte code ou encore de code source. La dernière solution permettant aux programmeurs
d’observer les effets du tissage. L’entrée, quant à elle, peut être sous forme de code source ou
de byte code. Une entrée sous forme de byte code permet de rendre orienté aspect une
application dont le code source n’est pas connu (une application commerciale par exemple).

Lorsque le tissage est effectué à l’exécution, le tisseur d’aspect se présente sous la forme
d’un programme qui permet d’exécuter à la fois l’application et les aspects. Les aspects ne
sont donc pas intégrés dans l’application à l’avance et existent encore individuellement à
l’exécution. Cette technique est intéressante car il est possible d’ajouter, de modifier ou
d’enlever des aspects au moment de l’exécution (runtime). Le tissage à l’exécution est aussi
appelé tissage dynamique.

1.4 Ordonnancement d’aspects

Etant donné qu’un aspect greffe des codes advices sur les points de jonction définis par sa
coupe, il se peut que plusieurs aspects aient des points de jonction en communs dans leur
coupe. Or dans certains cas, il est nécessaire qu’un code advice soit exécuté avant un autre
(s’il y a des dépendances entre aspects.). Les outils de la POA fournissent à cet effet des
techniques permettant de spécifier l’ordre dans lequel doivent être tissés les aspects. Si le
programmeur ne spécifie pas d’ordre, aucune garantie n’est donnée en général quant à l’ordre
résultant après le tissage. Cependant, certains outils tels qu’AspectJ proposent des règles
implicites d’ordonnancement d’aspects.

16
CHAPITRE 1 – LE PARADIGME ASPECT 17

1.5 Etapes de Développement d'une Application Orientée Aspect

L'implémentation d'une application orientée aspect peut se dérouler en 3 étapes comme


illustré à la figure 1.6 :

Figure 1.6 - Intégration du code des composants et des aspects pour former le système final

1. La décomposition des éléments du système: Il s'agit donc d'identifier tous les


composants et aspects. On sépare toutes les préoccupations, qu'elles soient fonctionnelles ou
non.

2. L'implémentation de chaque préoccupation: Chaque problématique sera codée


séparément dans un composant ou un aspect. Dans un aspect, le programmeur définit aussi les
règles d'intégration de l'aspect avec les composants concernés.

3. L'intégration du système: Tout langage OA offre un mécanisme d'intégration appelé


tisseur "weaver". Le tisseur, à l'image d'un métier à tisser, va donc composer le système final
sur base des règles et des modules qui lui ont été donnés.

17
CHAPITRE 1 – LE PARADIGME ASPECT 18

1.6 Langages à aspects

Ayant présenté en détail le paradigme de la programmation par aspects d’un point de vue
conceptuel et général, nous découvrons dans ce qui suit, les langages de programmation par
aspects. Et en particulier AspectJ, une extension du langage Java permettant la
programmation par aspects.

1.9.2 Présentation d'AspectJ

AspectJ [Xer02], est une extension de Java permettant la programmation par aspects. En
choisissant Java comme langage de base, AspectJ profite de l’ensemble des bénéfices de Java
et rend ainsi facile, pour des programmeurs Java, son utilisation. AspectJ est qualifié
d’extension « compatible » du langage Java [KHH+01] dans la mesure où :

· Chaque programme valide Java est un programme valide AspectJ.

· Tous les programmes valides AspectJ sont capables de s’exécuter sur n’importe quelle
machine virtuelle Java.

· Il est possible d’étendre l’ensemble des outils Java pour supporter AspectJ, ceci inclut
les IDEs, les outils de documentation, et les outils de conception;

· Le style de programmation avec AspectJ est très proche de celui de la programmation


par Java.

Etant un langage de programmation par aspects, AspectJ est une spécification d’un
langage aussi bien qu’un outil assurant le tissage des aspects et la compilation des codes
source.

1.6.1.1 Les points de jonction dans AspectJ

AspectJ utilise le terme de point de jonction (Join point) décrit dans la POA. Les points de
jonction représentent des points, bien définis, dans le flot d’exécution des composants
fonctionnels de l’application [Xer02]. Ce sont des éléments fondamentaux dans toute
implantation par aspects. Ils sont relatifs à l’ensemble des points où les aspects interagissent

18
CHAPITRE 1 – LE PARADIGME ASPECT 19

avec les composants. Un point de jonction peut être un simple appel à une méthode, une
réception d’un appel à une méthode ou encore une exécution d’une méthode (appelé
respectivement en anglais, method call, method call reception et method execution join point).
Nous distinguons aussi d’autres types de points de jonction de type lecture ou écriture d’un
attribut (appelé respectivement en anglais field get et field set joint point). Le tableau suivant
résume les différents types de point de jonction offerts par AspectJ.

Type de point de jonction Description

Method/constructor call Appel d’une méthode ou d’un constructeur d’objet

Method/constructor call Un objet reçoit un appel d’une méthode ou d’un


reception constructeur

Method/constructor execution Une méthode individuelle ou un constructeur sont


invoqués

Field get Accès en lecture à un attribut d’un objet d’une classe ou


d’une interface

Field set Accès en écriture à un attribut d’un objet ou d’une classe

Exeption handler execution Un « exception handler » est invoqué

Class initialization Initialisation des variables statiques d’une classe

Object initialization Initialisation d’un objet

Tableau 1.1 – Différents types de points de jonction offerts par AspectJ [KHH’01]

1.6.1.2 Les Coupes Transverses dans AspectJ

Une coupe transverse (pointcut) permet la définition des points de jonction à utiliser pour
composer chaque aspect avec les composants. C’est une collection de points de jonction et,

19
CHAPITRE 1 – LE PARADIGME ASPECT 20

optionnellement, de quelques paramètres précisant le contexte d’exécution au niveau de ces


points de jonction [KHH+01]. Elle est définie en utilisant les primitives suivantes :

• Calls (Signature)/ receptions(Signature): Permet de référencer les points de jonction


associés aux appels / réceptions d’appels de méthodes ou constructeurs dont la signature
correspond à Signature.

• gets (Attribut) / sets (Attribut): Permet de référencer les points de jonction correspondant
à l’accès aux attributs d’un objet. L’accès aux attributs est considéré comme un appel de
méthode.

• handles (ThrowableTypeName): Permet de référencer les points de jonction


correspondant au lancement de l’exception dont le type est donné par ThrowableTypeName.

• instanceOf (CurrentlyExecutingObjectTypeName) / within (ClassName) / withincode


(signature): Permet de référencer les points de jonction qui s’exécutent dans un objet de type
currentlyExecutingObjectTypeName, ou bien dans du code contenu dans la classe ClassName
ou encore dans le code défini dans une méthode dont la signature correspond à Signature.

Il est possible d’utiliser des expressions régulières pour définir des coupes transverses. Par
exemples :

• Receptions (* Point.*(..)) référence toutes les réceptions d’appels de toutes les méthodes
de la classe Point quels que soient leurs paramètres ou leur valeur de retour.

• Receptions (Point.new(..)) référence tous les constructeurs de la classe Point.

• Receptions (public * aPackage.*.*(int)) correspond à toutes les méthodes publiques qui


possèdent un paramètre de type int, de tous les objets du paquetage Java aPackage.

• Receptions (* Point.get*()) correspond à toutes les méthodes de la classe Point dont le


nom commence par get.

20
CHAPITRE 1 – LE PARADIGME ASPECT 21

1.6.1.3 Les Méthodes d’Aspect (advices) dans AspectJ:

Les méthodes d’aspect sont associées à des points de l’exécution d’une application (points
de jonction) afin d’en compléter le comportement. Les méthodes d’aspect ont une structure
proche de celle des méthodes Java. Elles permettent de décrire dans la syntaxe Java classique,
la manière dont les comportements des points de jonction associés sont modifiés, ceci selon
trois possibilités :

• Before, la méthode d’aspect sera exécutée avant la méthode associée au point de


jonction,

• After, la méthode d’aspect sera exécutée après la méthode associée au point de jonction,

• Around, la méthode d’aspect sera à la place de la méthode associée au point de jonction.

Voici un exemple de description d’une méthode d’aspect:

after() : moves() {

flag = true;

Cette méthode s’applique sur la coupe transverse appelée moves. Cette méthode d’aspect
est de type after(): elle ne sera exécutée qu’après la fin de l’exécution des méthodes associées
aux points de jonction de la coupe transverse moves. Les parenthèses vides de after()
indiquent que cette méthode d’aspect ne requiert aucun paramètre.

1.6.1.4 Aspect dans AspectJ

Un aspect est l’abstraction de plus haut niveau du langage AspectJ. Cette structure permet
d’encapsuler le code nécessaire à la modélisation d’une préoccupation transversale tout
comme une classe en Java permet d’encapsuler le code nécessaire à la modélisation d’un
objet.

21
CHAPITRE 1 – LE PARADIGME ASPECT 22

Un aspect est structurellement très proche d’une classe Java même si sa sémantique en est
différente. En plus de contenir les points de coupure et les greffons dont il a besoin, un aspect
peut déclarer des méthodes et des variables, étendre d’autres aspects ou classes et
implémenter des interfaces.

La différence majeure entre un aspect et une classe Java réside dans le fait qu’un aspect
ne peut pas être instancié à l’aide de l’instruction new. En effet l’instanciation des aspects
dans un système se fait via une phase de < tissage > (weaving).

1.6.1.5 Tissage (Weaving) dans AspectJ

Le tissage (weaving) est l’étape concrète qui permet d’injecter le comportement décrit par
des aspects dans un programme orienté objet. Le tissage se fait de façon statique grâce au
compilateur d'AspectJ.

1.7 La Modélisation Orientée-Aspect :

D’un point de vue du développement logiciel, le paradigme Aspect a émergé au niveau de


la programmation, avec notamment Aspect-J [KHH+01] qui a joué un rôle déterminant dans
l’émancipation de cette approche. Pourtant, à travers l’importance croissante de l’IDM, le
paradigme orienté-aspect ne s’est plus restreint au niveau de la programmation, et il s’étend
maintenant aux phases amonts du développement logiciel, par exemple au niveau de la
conception, de l’analyse [Cla01] ou encore de l’étude des exigences [AWK04, WA04,
RMA03, JN04] d’un système. Dans ce contexte, la modélisation orientée-aspect étend le
processus de développement de l’IDM (qui propose des transformations verticales), en
découpant le modèle d’un système en plusieurs préoccupations à un même niveau
d’abstraction, et en les composant à travers un processus de tissage qui peut être vu comme
une transformation “horizontale” de modèles.

1.7.1 Différentes Approches de Modélisation Orientées-Aspect

Il existe un grand nombre d’approches de modélisation orientées-aspect parmi lesquelles


nous citerons les approches suivantes :

22
CHAPITRE 1 – LE PARADIGME ASPECT 23

1.7.1.1 Approche de modélisation orientée-aspect de France et al.

L’approche de France et al. [FRGG04, RFLG04] est basée sur UML2.0, et elle a été
améliorée dans [RGF+06, RFG+05] en proposant des mécanismes de composition plus
aboutis, mais concernant essentiellement les diagrammes de classe. Les modèles d’aspects
(les préoccupations d’aspects modélisées) sont représentés en utilisant des “diagrammes
templates”. Plus précisément, ce sont des templates de diagrammes de classe et de
diagrammes de communications qui décrivent respectivement les parties structurelles et
comportementales des aspects. France et al. proposent également une brève description d’un
processus de conception de modélisation orientée-aspect.

L’approche de modélisation orientée-aspect de France et al. est une des approches


existantes les plus avancées. Ils proposent des mécanismes de composition évolués qui sont
réellement implantés et donc utilisables. Nous pouvons tout de même faire deux critiques
majeures à leur approche. Premièrement, ils ne proposent pas de mécanisme de détection de
points de jonction. Deuxièmement, les mécanismes de composition sont restreints aux
modèles statiques.

1.7.1.2 Approche de modélisation orientée-aspect de Stein et al.

Stein et al. [SHU] proposé une approche pour représenter des expressions de coupe à un
niveau de modélisation, appelée JPDD (pour join point designation diagrams en anglais).
L’idée intéressante de cette approche est d’offrir la possibilité d’utiliser le modèle le plus
adapté à l’expression de coupe souhaitée. Par exemple, pour exprimer la volonté de détecter
des séquences de messages, les diagrammes de séquences d’UML sont bien adaptés.. Des
caractères génériques et d’autres symboles sont utilisés pour augmenter l’expressivité de leurs
expressions de coupe.

Malheureusement, leur approche ne sert qu’à exprimer des expressions de coupe, mais pas
à détecter les points de jonction correspondants. Un travail important portant sur la faisabilité
de leurs JPDD et la proposition de mécanisme de détection correspondant, est nécessaire pour
que leur approche puisse être utilisée.

23
CHAPITRE 1 – LE PARADIGME ASPECT 24

1.7.1.3 L'Approche MATA (Modeling Aspects using a Transformation Approach)


[Whittle et al., 07a] [Whittle et al., 07b]

C'est une approche de composition de modèles d'aspect qui utilise les techniques de
transformation de modèle. La procédure de composition est asymétrique, car elle fait la
distinction entre un modèle de base et un modèle d'aspect. MATA définit un modèle d'aspect
comme une combinaison de deux parties dépendantes : un patron et une spécification de
composition. Le patron est utilisé pour détecter un emplacement dans le modèle de base où les
spécifications de composition seront appliquées. Même si les modèles d'aspect et le modèle de
base utilisent la même syntaxe concrète, ils sont différents à cause de la présence des
variables de patron, et des annotations utilisées par la spécification de composition.

MATA définit trois types d'annotations représentés par les stéréotypes create, delete et
context. Le stéréotype create est utilisé pour annoter les éléments qui vont être ajoutés dans le
modèle de base, alors que les éléments marqués par le stéréotype delete vont être supprimés
du modèle de base. Le stéréotype context est utilisé pour éviter d'appliquer un stéréotype à
plusieurs éléments dans le cas où un élément est annoté par un de ces stéréotypes et contient
d'autres éléments. Le processus de composition avec MATA se fait en deux temps : d'abord
un motif décrit par le patron de l'aspect est recherché dans le modèle de base, puis on procède
à la modification de ce motif selon la spécification de composition.

L'approche MATA a été développée initialement dans le contexte de la modélisation


orientée aspect. La technique de composition peut être généralisée à la composition de
plusieurs modèles, en considérant une chaîne de transformation par application successive de
modèles d'aspect. Bien que l'approche ne supporte a priori que la composition des
diagrammes de classes, des diagrammes de séquence et d'états d'UML, elle peut être adaptée à
d'autres modèles UML ou d'autres langages de modélisation décrits par un méta-modèle.

La particularité de cette approche est que les règles de transformation de graphe sont
définies en utilisant la syntaxe concrète du langage de modélisation. Cette propriété distingue
cette approche des approches de transformations les plus connues, par le fait que ces
approches définissent la transformation au niveau du méta-modèle, en utilisant la syntaxe
abstraite du langage de modélisation.

24
CHAPITRE 1 – LE PARADIGME ASPECT 25

1.8 Conclusion

Les problèmes d'entrelacement et d'éparpillement engendrent, généralement, un code de


pauvre qualité et difficile à réutiliser et à maintenir, ce qui fait de l'évolution du système
logiciel une tâche fastidieuse.

Pour mieux faire face à ces problèmes, une séparation des préoccupations est d'une
importance primordiale. Cette séparation a pour objectif d'encapsuler le comportement d'une
préoccupation transversale (Crosscutting concern) dans une unité appelée aspect tout en
restant indépendant des autres préoccupations fonctionnelles du système. Dans ce contexte, il
y a eu apparition des langages de programmation orientées aspect pour former le paradigme
de programmation orientée aspect POA (Aspect Oriented Programmation, AOP [KIL+97]).
Ce dernier était dédie, au début, à la phase d'implantation pour couvrir ensuite toutes les
phases du cycle de vie d'un logiciel.

25

Vous aimerez peut-être aussi