Visiteur en Go
Le Visiteur est un patron de conception comportemental qui permet d’ajouter de nouveaux comportements à une hiérarchie de classes sans modifier l’existant.
Découvrez pourquoi les visiteurs ne peuvent pas être remplacés par la surcharge de méthodes dans notre article Visiteur et double répartition.
Exemple conceptuel
Le patron de conception visiteur vous permet d’ajouter des comportements à une struct sans vraiment modifier la structure. Disons que vous vous occupez de maintenir une bibliothèque qui a différentes structs de formes comme :
- Carré
- Cercle
- Triangle
Chaque struct forme ci-dessus implémente l’interface commune Forme.
Dès que vos collègues ont commencé à utiliser votre super bibliothèque, vous avez été enseveli sous les demandes de fonctionnalités. Penchons-nous sur l’une des plus simples : une équipe vous a demandé de rajouter le comportement getArea
aux structs de formes.
Nous pouvons résoudre ce problème de plusieurs manières :
La première option qui vient à l’esprit est d’ajouter la méthode getArea
directement dans l’interface forme et de l’implémenter dans chaque struct de forme. À première vue, cela semble être la meilleure solution, mais elle a un certain coût. En tant que responsable de la bibliothèque, vous ne voulez pas risquer d’endommager votre précieux code chaque fois que quelqu’un réclame un nouveau comportement. Mais vous voulez tout de même que les autres équipes aient la possibilité d’étendre votre code.
La deuxième option est que l’équipe qui demande la fonctionnalité l’implémente elle-même. Ce n’est pas toujours possible, car le comportement peut dépendre de code privé.
La troisième option est de résoudre le problème en utilisant le patron de conception visiteur. Nous commençons par définir une interface Visiteur comme ci-dessous :
Les fonctions visitForSquare(square)
, visitForCircle(circle)
, visitForTriangle(triangle)
nous permettent d’ajouter des fonctionnalités respectivement aux carrés, cercles et triangles.
Vous vous demandez pourquoi on ne peut pas avoir une seule méthode visit(shape)
dans l’interface visiteur ? La raison est tout simplement que le Go ne gère pas la surcharge de méthodes. On ne peut donc pas définir des méthodes avec un même nom et des paramètres différents.
La deuxième partie du travail consiste à ajouter la méthode accept
à l’interface Forme.
Toutes les structs de formes doivent définir cette méthode comme ceci :
Attendez une minute, n’ai-je pas dit que nous ne voulions pas modifier nos structs de formes existantes ? Malheureusement, lorsque l’on utilise le visiteur, nous devons forcément modifier nos structs de formes, mais cette modification ne devra être faite qu’une seule fois.
Dans le cas où nous voulons ajouter d’autres comportements comme getNumSides
ou getMiddleCoordinates
, nous utiliserons la même fonction accept(v visitor)
sans apporter d’autres modifications aux structs de formes.
Au final, nous ne modifierons qu’une seule fois la struct forme, et toutes les futures demandes pour les nouveaux comportements seront gérées en utilisant cette même fonction accept. Si une équipe demande le comportement getArea
, nous pouvons simplement définir une implémentation concrète de l’interface visiteur et y écrire la logique de calcul de la surface.