Visitor

Catégorie

Pattern comportemental

Problème

Représenter une nouvelle opération à exécuter sur des éléments d’une structure d’objets sans modifier les classes des éléments. Utile lorsque vous devez effectuer de nombreuses opérations différentes sur une structure d’objets complexe et souhaitez séparer les opérations des classes d’objets.

Solution

  • Créer une interface Visitor avec une méthode visit() pour chaque type d’élément concret
  • Chaque élément concret implémente une méthode accept() qui appelle le visitor
  • Le visitor effectue l’opération, accédant à l’état interne de l’élément

Structure

  • Visitor : Déclare une opération visit pour chaque type d’élément
  • ConcreteVisitor : Implémente les opérations pour chaque type d’élément
  • Element : Déclare une méthode accept() prenant un visitor
  • ConcreteElement : Implémente accept() pour appeler l’opération du visitor
  • ObjectStructure : Peut énumérer ses éléments ; peut fournir une interface de haut niveau pour accepter les visitors

Avantages clés

  • Ajout facile de nouvelles opérations — De nouveaux visitors peuvent être ajoutés sans modifier les classes d’éléments
  • Regroupement des opérations liées — Les opérations liées sont dans une seule classe visitor
  • Accumulation d’état — Les visitors peuvent accumuler un état à travers les visites

Compromis

  • Difficile d’ajouter de nouveaux types d’éléments — Nécessite des modifications de l’interface Visitor et de tous les visitors concrets
  • Violation de l’encapsulation — Les visitors ont souvent besoin d’accéder à l’état interne des éléments

Quand l’utiliser

  • Une structure d’objets contient de nombreuses classes avec des interfaces différentes, et vous devez effectuer des opérations qui dépendent de leurs classes concrètes
  • Vous devez effectuer de nombreuses opérations non liées sur des éléments d’une structure
  • Vous souhaitez ajouter de nouvelles opérations sans modifier les classes d’éléments

Exemples