Souplesse et modularité grâce aux Design Patterns


précédentsommairesuivant

2.2. Ajout de traitements

Dans cette section, nous allons nous intéresser à un pattern particulier: le pattern Visitor, qui permet de séparer de manière très simple les données et les traitements associés.



2.2.1. Visitor

Le pattern Visiteur permet une séparation précise entre données et traitements. Il est le compagnon idéal du pattern Composite.



Avec le pattern Visiteur, on obtient 2 hiérarchies distinctes :

  • la hiérarchie des objets support de données
  • la hiérarchie des Visiteurs (contenant les traitements sur les données)
Visiteur
Le pattern Visiteur



D'un point de vue implémentation, cela nous donne :

Code d'un objet visité
Sélectionnez

void ObjetDeTypeA::accept( Visitor * v ) {
  v->visitObjetDeTypeA( this ) ;
}
Implémentation d'un visiteur
Sélectionnez

void MonVisiteur::visitObjetDeTypeA( ObjetDeTypeA * objet ) {
  // Traitement d'un objet de type A

}


void MonVisiteur::visitObjetDeTypeB( ObjetDeTypeB * objet ) {
  // Traitement d'un objet de type B

}


void MonVisiteur::visitObjetDeTypeC( ObjetDeTypeC * objet ) {
  // Traitement d'un objet de type C

}



Pour appliquer un visiteur, on procède de la sorte :

Application d'un visiteur
Sélectionnez
  unObjet->accept( unVisiteur ) ;



Voici alors ce qu'il se passe (admettons que unObjet soit de type ObjetDeTypeA) :

  1. la méthode accept de ObjetDeTypeA est appelée
  2. la méthode visitObjetDeTypeA du visiteur v est alors appelée avec comme paramètre this (notre objet de type ObjetDeTypeA)
  3. on entre alors dans le corps de la méthode visitObjetDeTypeA du visiteur. Le paramètre obj fait référence à l'objet de type ObjetDeTypeA sur lequel on applique notre traitement



Intérêt du pattern Visitor :

Pour ajouter un traitement à notre application, il suffit donc de créer un nouveau Visiteur avant de surcharger les méthodes permettant de visiter les différents objets de la hierarchie. Ensuite, pour utiliser le visiteur, on fait:

Application d'un visiteur
Sélectionnez
  monObjet->accept( monVisiteur ) ;

De cette manière, on peut facilement ajouter de nouveaux traitements sans toucher à la hiérarchie de nos objets (en POO "classique", on aurait implémenté de nouvelles méthodes pour ajouter de nouvelles fonctionnalités). Grâce aux Visiteurs :

  • le code est plus clair (des fonctionnalités différentes se trouvent dans des Visiteurs différents)
  • des équipes différentes peuvent travailler sur des fonctionnalités différentes sans gêner les autres équipes
  • on n'est pas obligé de tout recompiler à chaque ajout d'une fonctionnalité (seul le code du Visiteur est recompilé)



Exemple d'application :

Imaginons que nous ayons une scène 3D, représentée à l'aide du pattern Composite. On peut vouloir choisir plusieurs modes d'affichage pour cette scène 3D: aperçu en fils de fer, non texturé, texturé et avec différents effets (bump mapping, anti-aliasing...), ou photo-réaliste au moyen de lancés de rayons. Pour cela, on met en place des Visiteurs spécifiques à chaque mode d'affichage. Cela permet de structurer le programme et de pouvoir facilement ajouter de nouvelles fonctionnalités (ex: calculer la complexité d'une scène) par simple ajout de Visiteurs.




précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Copyright © 2006 Pierre Caboche. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.