« Patrons de conception/Visiteur » : différence entre les versions
Contenu supprimé Contenu ajouté
m 8 versions depuis w:Visiteur (patron de conception) : Patrons de conception/Visiteur |
+ |
||
Ligne 1 :
<noinclude>{{Patrons de conception}}
{{Patron de conception|Visiteur|Visitor|Découpler classes et traitements, afin de pouvoir ajouter de nouveaux traitements sans ajouter de nouvelles méthodes aux classes existantes}}</noinclude>
Le ''visiteur'' est une manière de séparer un [[algorithme]] d'une [[structure de données]].
Un visiteur possède une méthode par type d'objet traité.
Pour ajouter un nouveau traitement, il suffit de créer une nouvelle classe dérivée de la classe Visiteur.
On a donc pas besoin de modifier la structure des objets traités, contrairement à ce qu'il aurait été obligatoire de faire si on avait implémenté les traitements comme des méthodes de ces objets.
L'avantage du patron visiteur est qu'un visiteur peut avoir un état.
Ce qui signifie que le traitement d'un type d'objet peut différer en fonction de traitements précédents.
Par exemple, un visiteur affichant une structure arborescente peut présenter les nœuds de l'arbre de manière lisible en utilisant une indentation dont le niveau est stocké comme valeur d'état du visiteur.
== Exemples ==
=== [[Programmation C++|C++]] ===
Prenons une classe <tt>ObjetPere</tt>, de laquelle hériteront <tt>Objet1, Objet2 et Objet3</tt>, elles posséderont la méthode <tt>accept(Visitor v)</tt>.
<source lang="cpp">
{ v->visitObjetDeType1( this )
</source>
Créons la classe <tt>Visitor</tt>, dont hériteront <tt>Visiteur1</tt> et <tt>Visiteur2</tt>.
Dans chacun de ces objets, on retrouvera une <source lang="cpp">
{ // Traitement d'un objet de type 1
{ // Traitement d'un objet de type 2
{ // Traitement d'un objet de type 3
</source>
=== [[Programmation Java|Java]] ===
L'exemple suivant montre comment afficher un arbre de nœuds (les composants d'une voiture).
Au lieu de créer des méthodes d'affichage pour chaque sous-classe (Wheel, Engine, Body, et Car), une seule classe est créée (CarElementPrintVisitor) pour afficher les éléments.
Parce que les différentes sous-classes requiert différentes actions pour s'afficher proprement, la classe CarElementPrintVisitor répartit l'action en fonction de la classe de l'argument qu'on lui passe.
<source lang="java">
interface CarElementVisitor
{
void visit(Wheel wheel);
void visit(Engine engine);
void visit(Body body);
void visitCar(Car car);
}
interface CarElement
{
void accept(CarElementVisitor visitor);
// Méthode à définir par les classes implémentant CarElements
}
class Wheel implements CarElement
{
private String name;
Wheel(String name)
{
this.name = name;
}
String getName()
{
return this.name;
}
public void accept(CarElementVisitor visitor)
{
visitor.visit(this);
}
}
class Engine implements CarElement
{
public void accept(CarElementVisitor visitor)
{
visitor.visit(this);
}
}
class Body implements CarElement
{
public void accept(CarElementVisitor visitor)
{
visitor.visit(this);
}
}
class Car
{
CarElement[] elements;
public CarElement[] getElements()
{
return elements.clone(); // Retourne une copie du tableau de références.
}
public Car()
{
this.elements = new CarElement[]
{
new Wheel("front left"),
new Wheel("front right"),
new Wheel("back left"),
new Wheel("back right"),
new Body(),
new Engine()
};
}
}
class CarElementPrintVisitor implements CarElementVisitor
{
public void visit(Wheel wheel)
{
System.out.println("Visiting "+ wheel.getName() + " wheel");
}
public void visit(Engine engine)
{
System.out.println("Visiting engine");
}
public void visit(Body body)
{
System.out.println("Visiting body");
}
public void visitCar(Car car)
{
System.out.println("\nVisiting car");
for(CarElement element : car.getElements())
{
element.accept(this);
}
System.out.println("Visited car");
}
}
class CarElementDoVisitor implements CarElementVisitor
{
public void visit(Wheel wheel)
{
System.out.println("Kicking my "+ wheel.getName());
}
public void visit(Engine engine)
{
System.out.println("Starting my engine");
}
public void visit(Body body)
{
System.out.println("Moving my body");
}
public void visitCar(Car car)
{
System.out.println("\nStarting my car");
for(CarElement carElement : car.getElements())
{
carElement.accept(this);
}
System.out.println("Started car");
}
}
public class VisitorDemo
{
static public void main(String[] args)
{
Car car = new Car();
CarElementVisitor printVisitor = new CarElementPrintVisitor();
CarElementVisitor doVisitor = new CarElementDoVisitor();
printVisitor.visitCar(car);
doVisitor.visitCar(car);
}
}
</source>
== Lien externe ==
* {{fr}} [http://pcaboche.developpez.com/article/design-patterns/programmation-modulaire/?page=page_5 Article sur Développez.com]
|