« 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}}
{{Ébauche|informatique}}
{{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>
 
En [[génie logiciel]], unUn '''visiteur''' est le nom d'une des structures de [[../|patron de conception]] [[patron../Patrons de conception#Comportementcomportement|comportemental]].
 
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++]] ===
== Exemple ==
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>.
 
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">
void ObjetDeType1::accept( Visitor * v )
{
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 methodeméthode <tt>visiterObjet1(Objet1 a)</tt>, <tt>visiterObjet2(Objet2 b)</tt> et <tt>visiterObjet3(Objet3 c)</tt>.
 
<source lang="cpp">
void MonVisiteur::visitObjetDeType1( ObjetDeType1 * objet )
{
// Traitement d'un objet de type 1
}
void MonVisiteur::visitObjetDeType2( ObjetDeType2 * objet )
{
// Traitement d'un objet de type 2
}
void MonVisiteur::visitObjetDeType3( ObjetDeType3 * objet )
{
// Traitement d'un objet de type 3
}
</source>
 
=== [[Programmation Java|Java]] ===
== Lien externe ==
 
L'exemple suivant montre comment afficher un arbre de nœuds (les composants d'une voiture).
* {{fr}} [http://pcaboche.developpez.com/article/design-patterns/programmation-modulaire/?page=page_5 Article sur Développez.com]
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">
[[Catégorie:Patron de conception]]
interface CarElementVisitor
{
void visit(Wheel wheel);
void visit(Engine engine);
void visit(Body body);
void visitCar(Car car);
}
 
interface CarElement
[[de:Besucher (Entwurfsmuster)]]
{
[[en:Visitor pattern]]
void accept(CarElementVisitor visitor);
[[es:Visitor (patrón de diseño)]]
// Méthode à définir par les classes implémentant CarElements
[[it:Visitor]]
}
[[pl:Wzorzec wizytatora]]
 
[[pt:Visitor]]
class Wheel implements CarElement
[[vi:Visitor pattern]]
{
[[zh:访问者模式]]
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]