Ces dernières années, l’im­por­tance de la pro­gram­ma­tion orientée objet (OOP), une sous-forme du paradigme de pro­gram­ma­tion im­pé­ra­tive, n’a cessé de croître. Par rapport à d’autres styles de pro­gram­ma­tion, l’option qui consiste à décrire tous les modules d’un projet logiciel comme un objet, dont le com­por­te­ment peut être défini par des classes cor­res­pon­dantes, présente plusieurs avantages décisifs. Pour de nombreux dé­ve­lop­peurs, la pos­si­bi­lité de réu­ti­li­ser fa­ci­le­ment des parties du programme déjà conçues est un argument évident en faveur de l’uti­li­sa­tion d’une OOP.

Pour faciliter encore la réu­ti­li­sa­bi­lité ainsi que l’im­plé­men­ta­tion, l’adap­ta­bi­lité et la tes­ta­bi­lité des objets intégrés, quatre in­for­ma­ti­ciens ont publié les patrons de con­cep­tion GoF dans l’ouvrage « Design Patterns: Elements of Reusable Object-Oriented Software ». Parmi cette vingtaine de patrons de con­cep­tion, on trouve le Visitor pattern ou Visitor design pattern (en français : patron de con­cep­tion Visiteur) que nous dé­tail­lons pour vous dans les pa­ra­graphes suivants.

Qu’est-ce que le Visitor pattern ?

Le Visitor design pattern, abrégé en Visitor pattern, fournit une solution pour séparer un al­go­rithme de la structure de l’objet sur lequel il travaille. Il décrit une méthode pour ajouter de nouvelles opé­ra­tions à des struc­tures d’objets exis­tantes sans que ces struc­tures aient besoin d’être modifiées. Grâce à cette ca­rac­té­ris­tique, le Visitor pattern peut être utilisé pour mettre en œuvre le principe ouvert/fermé. Ce principe du dé­ve­lop­pe­ment logiciel orienté objet repose sur le fait que chaque unité d’un logiciel – telles que les modules, les classes ou les méthodes – est à la fois ouverte (open) aux ex­ten­sions et fermée (closed) aux mo­di­fi­ca­tions.

Note
En français, on désigne également le Visitor Pattern sous les termes « patron de con­cep­tion Visiteur » ou « patron Visiteur ».

Le Visitor pattern est l’un des 23 patrons de con­cep­tion (catégorie : patron com­por­te­men­tal) décrits et publiés en 1994 par les in­for­ma­ti­ciens Erich Gamma, Richard Helm, Ralph Johnson et John Vlissides. Ces quatre in­for­ma­ti­ciens étant connus sous le nom de « Gang of Four » (fr. bande de quatre ; GoF), l’ap­pel­la­tion patrons de con­cep­tion GoF s’est établie pour désigner ces design patterns.

À quoi sert le Visitor pattern ?

Lorsque la structure de l’objet est composée de nom­breuses classes et que de nouvelles opé­ra­tions sont souvent né­ces­saires, il est très laborieux pour les dé­ve­lop­peurs de devoir im­plé­men­ter une nouvelle sous-classe pour chaque nouvelle opération. En procédant de la sorte, le système obtenu dis­po­se­rait de dif­fé­rentes classes de nœud qui seraient non seulement trop com­pli­quées à com­prendre mais aussi à en­tre­te­nir et à modifier. L’instance décisive du Visitor pattern, le visiteur (Visitor), permet d’ajouter de nouvelles fonc­tion­na­li­tés vir­tuelles à une famille de classes sans avoir à les modifier.

Note
Les fonc­tion­na­li­tés ou les méthodes vir­tuelles dé­fi­nis­sent les fonc­tion­na­li­tés cibles à exécuter dont le but n’a pas à être connu au moment de la com­pi­la­tion. Il s’agit d’un outil essentiel des langages orientés objet.

Le patron de con­cep­tion Visiteur prévoit une dé­fi­ni­tion séparée de l’objet visiteur dans l’idée d’im­plé­men­ter une opération qui sera exécutée sur un ou plusieurs éléments de la structure de l’objet. Les clients accédant à la structure de l’objet appellent ensuite des méthodes (par ex. « accept(visitor) ») sur l’élément concerné. Ces méthodes délèguent la requête à l’objet visiteur accepté qui peut ensuite exécuter l’opération concernée.

Re­pré­sen­ta­tion graphique du Visitor pattern (diagramme UML)

La façon la plus simple d’illustrer l’in­te­rac­tion entre les éléments existants et les objets visiteurs intégrés selon le Visitor pattern est d’utiliser une re­pré­sen­ta­tion graphique des relations et des processus d’un potentiel logiciel orienté objet. Très apprécié, le langage de mo­dé­li­sa­tion UML (Unified Modeling Language) est idéal pour cela. C’est la raison pour laquelle nous l’avons utilisé dans le diagramme de classes suivant re­pré­sen­tant le Visitor pattern.

Avantages et in­con­vé­nients du Visitor pattern

Le Visitor pattern constitue un moyen éprouvé et efficace d’étendre les unités exis­tantes d’un logiciel orienté objet. Une nouvelle opération peut fa­ci­le­ment être ajoutée en dé­fi­nis­sant un nouveau visiteur. Cette méthode permet d’ailleurs également de cen­tra­li­ser le code fonc­tion­nel : l’im­plé­men­ta­tion cor­res­pon­dant à une opération est cen­tra­li­sée dans la classe visiteur et n’a pas à être complétée dans les autres classes in­di­vi­duelles. Pour faire simple, l’avantage décisif d’un logiciel conçu selon le Visitor pattern réside dans le fait que le code source des objets utilisés n’a pas à être cons­tam­ment ajusté. À la place, la logique est répartie entre les visiteurs, agissant comme des rem­pla­çants, et les classes de visiteurs.

Il va de soi que le patron de con­cep­tion Visiteur n’est pas ir­ré­pro­chable. En adoptant les principes de ce patron, les dé­ve­lop­peurs doivent être cons­cients des éléments suivants : toutes les mo­di­fi­ca­tions apportées à la classe d’un élément, même les plus petites, en­traî­nent gé­né­ra­le­ment un ajus­te­ment des classes visiteurs affectées. Par ailleurs, ce patron n’évite pas le travail sup­plé­men­taire né­ces­saire pour in­tro­duire de nouveaux éléments a pos­te­riori puisqu’il faudra également im­plé­men­ter pour ces éléments des méthodes visit() qui devront à leur tour être ajoutées dans les classes Con­cre­te­Vi­si­tor. La re­mar­quable mo­du­la­rité des unités lo­gi­cielles n’est donc pas obtenue sans efforts.

Dans quel cas le Visitor pattern est-il utilisé ?

Le Visitor pattern peut con­si­dé­ra­ble­ment sim­pli­fier les tâches ré­cur­rentes en dé­ve­lop­pe­ment logiciel. Il est in­té­res­sant de se pencher de plus près sur ce patron de con­cep­tion, en par­ti­cu­lier pour les dé­ve­lop­peurs suivant le paradigme de la pro­gram­ma­tion orientée objet. Depuis sa pré­sen­ta­tion en 1994, ce patron est parvenu à s’imposer dans le milieu de la pro­gram­ma­tion, le type de projet logiciel ne jouant en principe aucun rôle décisif dans l’utilité de ce patron. En ce qui concerne les langages de pro­gram­ma­tion pouvant en bé­né­fi­cier, il n’existe en principe aucune res­tric­tion concrète pour ce patron, si ce n’est qu’il est tout par­ti­cu­liè­re­ment adapté au paradigme orienté objet.

Le Visitor pattern joue notamment un rôle fon­da­men­tal dans les langages suivants :

  • C++
  • C#
  • Java
  • PHP
  • Python
  • Ja­vaS­cript
  • Golang
iueor-qViR4.jpg Pour afficher cette vidéo, des cookies de tiers sont nécessaires. Vous pouvez consulter et modifier vos paramètres de cookies ici.

Exemple pratique de l’uti­li­sa­tion du Visitor pattern

D’un point de vue extérieur, il n’est pas toujours simple de com­prendre l’uti­li­sa­tion et l’utilité du Visitor pattern. De nos jours, toute personne sou­hai­tant apprendre la pro­gram­ma­tion sera pourtant con­fron­tée à ce patron et à sa mise en œuvre.

Pour expliquer le patron de con­cep­tion Visiteur, on utilise souvent une analogie facile à com­prendre, celle du trajet en taxi : un client réserve un taxi qui peut venir le prendre au pas de sa porte. Lorsque la personne est assise dans le taxi, « qui lui rend visite », le taxi (ou son con­duc­teur) dispose d’un contrôle total sur le transport de la personne.

L’analogie des achats dans un su­per­mar­ché est elle aussi souvent utilisée pour expliquer le fonc­tion­ne­ment du Visitor pattern : dans son caddy, la personne réalisant les achats rassemble les articles qu’elle désire. Ces achats re­pré­sen­tent l’ensemble des éléments de la structure de l’objet. Une fois à la caisse, le caissier tient le rôle du visiteur scannant les prix et le poids des dif­fé­rents articles (ou éléments) afin de calculer le coût total à payer.

Exemple de code selon l’approche du Visitor pattern (PHP)

Pour finir, le code suivant présente une mise en œuvre simple et basique du Visitor pattern en PHP.

return ‘B’;
	}
	public function getData() {
		return $this->the_data;
	}
	public function accepter(visiteur $visiteur) {
		$visiteur->VisiteDeLElementB($this);
	}
}
abstract class visiteur {
	abstract function VisiteDeLElementA(ElementA $elem);
	abstract function VisiteDeLElementB(ElementB $elem);
}
class visiteur1 extends visiteur{
	private $characteristics;
	public function getCharacs() {
		return $this->characteristics;
	}
	public function VisiteDeLElementA(ElementA $elem) {
		$this->characteristics = ‘Info:’.$elem->getInfo();
	}
	public function VisiteDeLElementB(ElementB $elem) {
		$this->characteristics = ‘DATA:’.$elem->getData().’!!’;
	}
}
function Test() {
	write_line(‘début du test’);
	// Structure de l’objet
	$elemente = array (
		new ElementA(‘Bonjour’, ‘Nouveau !!’),
		new ElementB(‘Enfin.’),
	);
	$bes1 = new visiteur1();
	foreach ($elemente as $element) {
		$element->accepter($vis1);
		write_line(‘Après la visite de l’élément’.$element->getName().’: ‘.$bes1-			>getCharacs());
}
}
function write_line($text) {
	print $text.’<br>‘;
}
Test();

L’extrait de code ressemble alors à ce qui suit :

Début du test
Après la visite de l’élément A : Info:[Bonjour--Nouveau !!]
Après la visite de l’élément B : DATA:(Enfin.)!!
Aller au menu principal