• Aucun résultat trouvé

3 Générateur d’une seule instance à la fois:

3.3 Instance du pattern ‘Adapter’ :

Le pattern ‘Adapter’ convertit l’interface d’une classe en une interface distincte, conforme à l’attente de l’utilisateur. Adapter permet à des classes de travailler ensemble, qui n’auraient pu le faire autrement pour causes d’interfaces incompatibles.[Gamma et al., 1995].

Ajouter et supprimer un Conrete Colleague.

Effacer les champs des noms des classes, ainsi les attributs et les

méthodes. Affichage du

diagramme de classes du pattern.

Génération du code orienté aspect de l’instance qui ce trouve dans le modèle

conceptuel. Considérer la classe Client comme la

classe Main, si cette option est cochée.

3.3.1 Présentation du pattern ‘Adapter’ en O.O:

Ce pattern constitue de quatre participants qui sont : Adapter, Adaptee, Target, et, Client. Où :

Target : Définit l'interface métier utilisée par le Client.

Client : Travaille avec des objets implémentant l'interface Target. Adaptee : Définit une classe existante devant être adaptée.

Adapter : Fait correspondre la classe Adaptee à l'interface Target.

Nous allons considérer une instance du pattern ‘Adapter’ dans un contexte de réalisation où les participants de cette instance portent les mêmes noms de ceux du pattern lui-même (contexte général). La figure 4.3 représente le modèle conceptuel (représenté par le diagramme de classes) de ce pattern.

Figure 4.3. Instance du pattern ‘Adapter’ au niveau conceptuel représenté par le diagramme de classes.

Le modèle physique (représenté par le langage Java) d’une instance du pattern ‘Adapter’ dans le contexte général est illustré dans la figure 4.4.

Figure 4.4. Instance du pattern ‘Adapter’ au niveau physique représenté par le langage Java. // La classe Client

public class Client {

}

// La classe Adapter implementant l'interface Target

public class Adapter implements Target {

private Adpatee adaptee;

public void Request () {adaptee.SpecificRequest();}

}

// L'interface Target

public interface Target {

public void Request();}

// La classe Adaptee

public class Adaptee {

public void SpecificRequest(){}

3.3.2 Transformation de ‘Adapter’ :

Le pattern Adapter est directement implémenté grâce aux mécanismes Aspect d’extension d’interfaces [Hannemann et Kiczales, 2002]. La transformation en AspectJ est d’utiliser le concept d’introduction offert par ce langage permet de doter directement la classe impactée Adaptee par une nouvelle interface conforme à celle du Target (interface requise par le classe Client), tout en lui ajoutant les opérations nécessaires (Requeste()). Chacune des opérations nouvellement introduites fait, tout simplement, appel à son opération correspondante spécifique à la classe impactée (RequeteSpecifique())[Hachani 2006].

a) Avantages de la transformation :

L’implémentation du pattern ‘Adapter’ à l’aide de l’approche aspect permet de bénéficier des avantages suivants : la localisation, la composition et l’adaptabilité. [Hannemann et Kiczales, 2002].

Du point de vue de la localisation, il n’y a pas la classe Adapter pour contenir le code gérant l’adaptation. Par ailleurs, l’essentiel de cette gestion est implémenté dans un aspect concret. Ce dernier contient la spécificité de la classe Adapter.

Du point de vue de la composition, la classe Adapter (si elle contient d’autres méthodes que la méthode d’adaptation) peut participer sans difficulté à d’autre instances.

Du point de vue de l’adaptabilité, le lien entre les classes Adapter et les classes Adaptee est beaucoup plus faible que précédemment. Il est possible d’avoir une gestion complexe des Adapter et Adaptee. Par exemple, la gestion de plusieurs Adapter et Adaptee dans un seul aspect.

b) Principe de transformation :

Avant d’entamer l’algorithme de transformation, nous allons décrire les opérations effectuées par ce dernier d’une manière concrète. Il génère un aspect concret qui porte le même nom de la classe Adapter. Cet aspect concret contient la déclaration inter-type entre l’interface Target et la classe Adaptee (modification hiérarchie d’héritage des classes). La raison de la déclaration inter-type pour que le mécanisme d’introduction soit possible (introduire la méthode Request dans la classe Adaptee). Il génère aussi les classes suivante : Client, Target, et Adaptee. Cette génération est purement orientée objet.

Si nous comparons la solution objet par rapport la solution aspect, nous remarquons que la classe Adapter est remplacée par un aspect. (suppression de la classe, puis l’ajout d’un aspect).

c) Algorithme de transformation :

L’algorithme suivant transforme une instance du pattern ‘Adapter’ de l’orienté objet vers l’orienté aspect dans les deux niveaux conceptuel et physique.

Transformation_Adapter (Classe Client, Interface Target, Classe Adapter, Classe Adaptee)

Debut

Créer Classe client {

Nom_de_classe := Client.nom_de_classe ; Type_de_classe :=Concrete ;

Heritage := « » ;

Attributs :=Client.Attributs ; Operations :=Client.Operations ;} Créer Interface target {

Nom_de_interface := Target.nom_de_interface ; Heritage := « » ;

Operations := « » ;} Créer Aspect adapter {

Nom_de_aspect :=Adapter.nom_de_classe ; Type_de_aspect :=Concret ;

Heritage := « » ;

Declare_parents :={Adaptee.nom_de_classe implements Target.nom_de_interface} Declare_introd_operation :=

{Adaptee.nom_de_classe’.’Adapter.operations(Requete).signature} Declare_introd_operation

(Adaptee.nom_de_classe’.’Adapter.operations(Requete).signature) := {Operation(RequeteSpecifique).appel ;}}

Créer Classe adaptee {

Nom_de_classe := «Adaptee» ; Type_de_classe :=Concrete ; Heritage := « » ;

Attributs :={private Adaptee.nom_de_classe adaptee} Operations :=Adaptee.Operations() ;} Si Modèle=Conceptuel alors Debut AfficherNote(Adapter,Adapter) ; VérifierLien() ; Fin Fin

d) Résultat de la transformation :

Apres l’application de l’algorithme de transformation dans le contexte de réalisation générale, nous obtenons le modèle conceptuel (représenté par le diagramme de classes pour AspectJ) illustré dans la figure 4.5.

Figure 4.5. Instance du pattern ‘Adapter’ au niveau conceptuel O.A représenté par le diagramme de classe UML pour AspectJ.

Le modèle physique (représenté par le langage AspectJ) obtenu après la transformation est illustré dans la figure 4.6.

Figure 4.6. Instance du pattern ‘Adapter’ au niveau physique O.A représenté par le langage AspectJ.

//La classe Client

public class Client {

}

// L'aspect Adapter

public aspect Adapter {

declare parents: Adaptee implements Target ;

public void Adaptee.Request()

{ SpecificRequest();} }

//L'interface Target

public interface Target {

public void Request();}

// La classe Adaptee

public class Adaptee {

public void SpecificRequest(){}

3.3.3 Etude de cas :

Cette étude de cas est prise de l’exemple du pattern ‘Adapter’ de [Hannemann et Kiczales, 2002]. Dans ce cas, il y a une adaptation de la classe Ecran (est exactement la méthode afficher() ), par l’adaptateur la classe ImprEcran (à la méthode imprimer() ).(voir figure 4.7).

Figure 4.7. Instance du pattern ‘Adapter’ dans notre outil

La figure 4.8 montre un extrait du code aspect généré pour notre exemple Imprimante/Ecran.

Figure 4.8. Extrait du code généré de l’exemple étudié de ‘Adapter’.

Le code obtenu par le générateur n’est pas prêt à être exécuté (c’est un squelette de code). Il faut le compléter, c'est-à-dire il faut implémenter les différentes méthodes. L’annexe B présente le reste du code généré par l’outil, ainsi le code final (après une modification).

Puis le programme qui est obtenu par des modifications sera prêt à être exécuté. Il est déjà testé avec succès dans l’environnement Eclipse version 3.3.0 avec Eclipse AspectJ Development Tools version 1.5.0. Nous avons supposé que la méthode imprimer affiche un message à l’écran. (voir figure 4.9).

//L'aspect ImprEcran

public aspect ImprEcran {

declare parents: Ecran implements Imprimante ;

public void Ecran.imprimer() { afficher() ;}}

//L'interface Imprimante

Figure 4.9. Résultat de l’exécution de l’exemple étudié de ‘Adapter’