Question

Comme exercice pour moi-même, je traduisais un exemple de programme dans différentes langues.À partir de C#, j'avais une interface de modèle de visiteur comme celle-ci :

interface Visitor
    {
        void Accept(Bedroom x);
        void Accept(Bathroom x);
        void Accept(Kitchen x);
        void Accept(LivingRoom x);
    }

En passant à Ruby (ou Python, ou autre), je ne reçois plus de répartition du compilateur en fonction du type.Dois-je effectuer l'envoi chez le visiteur lui-même ?

class Cleaner

  def accept(x)
    acceptBedroom(x) if Bedroom === x
    acceptBathroom(x) if Bathroom === x
    acceptKitchen(x) if Kitchen===x
    acceptLivingRoom(x) if LivingRoom===x
  end

  ...

Ou dois-je faire le dispatch dans les différentes spécialisations de la salle :

class Bathroom<Room
  def initialize(name)
    super(name)
  end
  def accept(visitor)
    visitor.acceptBathroom(self)
  end
end

Ou existe-t-il un autre idiome préféré utilisé dans les langages dynamiques ?

Était-ce utile?

La solution

Ma recommandation est d’utiliser la première approche.Il y a des avantages et des inconvénients pour chaque approche.Le premier est plus difficile à maintenir à mesure que le nombre de types de chambres augmente ;ce dernier est plus difficile à mesure que le nombre de types de nettoyeurs augmente.

En Ruby, vous pouvez essayer

def accept(x)
  send "accept#{x.class}".to_sym, x
end

PS :Tous les langages typés dynamiquement ne sont pas incapables d'effectuer une répartition en fonction du type ;certains peuvent déduire le type, ou à défaut, peuvent utiliser le casting forcé pour choisir la méthode appropriée parmi les options surchargées.

Autres conseils

J'opterais pour la deuxième version.Le premier ressemble au genre d’odeur de code que Visitor est censé résoudre :longues instructions if-else-if ou switch-case.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top