Celui qui préoccupait le plus les auteurs de Design Patterns était le motif "Visiteur".
C'est un «mal nécessaire» - mais il est souvent surutilisé et le besoin d'en révéler souvent une faille plus fondamentale dans votre conception.
Un autre nom pour le modèle "Visiteur" est "Multi-dispatch", car le modèle Visiteur est ce que vous obtenez lorsque vous souhaitez utiliser un langage OO de répartition de type unique pour sélectionner le code à utiliser en fonction du type de deux (ou plus) différents objets.
L'exemple classique est que vous avez l'intersection entre deux formes, mais il y a un cas encore plus simple qui est souvent négligé: comparer l'égalité de deux objets hétérogènes.
Quoi qu'il en soit, vous vous retrouvez souvent avec quelque chose comme ceci:
interface IShape
{
double intersectWith(Triangle t);
double intersectWith(Rectangle r);
double intersectWith(Circle c);
}
Le problème avec ceci est que vous avez couplé ensemble toutes vos implémentations de "IShape". Vous avez laissé entendre que chaque fois que vous souhaitez ajouter une nouvelle forme à la hiérarchie, vous devrez également modifier toutes les autres implémentations "Shape".
Parfois, c'est la conception minimale correcte - mais réfléchissez-y. Votre conception exige- t-elle vraiment que vous deviez expédier sur deux types? Êtes-vous prêt à écrire chacune de l'explosion combinatoire des multi-méthodes?
Souvent, en introduisant un autre concept, vous pouvez réduire le nombre de combinaisons que vous allez devoir écrire:
interface IShape
{
Area getArea();
}
class Area
{
public double intersectWith(Area otherArea);
...
}
Bien sûr, cela dépend - parfois vous avez vraiment besoin d'écrire du code pour gérer tous ces différents cas - mais cela vaut la peine de prendre une pause et de réfléchir avant de sauter le pas et d'utiliser Visitor. Cela pourrait vous éviter beaucoup de douleur plus tard.