IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Design pattern visiteur et double double-dispatch ?


Sujet :

C++

  1. #1
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut Design pattern visiteur et double double-dispatch ?
    Bonjour,

    Quelques sujets parlant du design pattern visiteur et du double-dispatch on ravivé en moi une ancienne question qui sommeillait.

    J'ai deux classes mères :
    - Visitable dont chaque filles définie une méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    virtual void visiteMoi(Visiteur & v)
    {
              v.visite(*this);
    }
    - Visiteur qui défini pour chaque type de Visitable une méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    virtual void visite(Visitable &)
    {
               std::cerr << "visitable" << std::endl;
    }
     
    void visite(VisitableFille1 &)
    {
                std::cerr << "visitableFille1" << std::endl;
    }
    C'est génial, j'ai juste à hériter de Visiteur et de redéfinir quelques méthodes pour visiter n'importe quel Visitable.

    Tout content, je fais une petite bibliothèque, je la publie...
    Et un beau jour, un utilisateur de ma bibliothèque peut me contacter et me dire :
    Tu est bien gentil Neckara, mais moi je veux créer une nouvelle classe fille de Visitable et effectuer des traitements spécifiques avec les Visiteur que j'aurais créé
    Or pour faire ceci, il n'a que deux solutions :
    - réécrire la classe Visiteur pour inclure ses méthodes de traitements.
    - créer sa propre visite spécialisé (avec VisiteurPerso et VisitablePerso qui sont plus ou moins une copie de Visiteur et de Visitable) qu'on utilisera après avoir effectué la première visite et s'être aperçut qu'on visite des classes créés par l'utilisateur. Pour cela on fait hériter chaque Visiteur créé de Visiteur et de de VisiteurPerso et chaque Visitable créé de VirtualVisitablePerso et de VisitablePerso en n'oubliant pas d'inclure un class VirtualVisitablePerso : public Visitable{ virtual void visiteMoi(Visiteur &)=0;} à la bibliothèque.

    Je me demandais s'il n'existait justement pas d'autres solutions/astuces pour éviter ce problème.
    Comme faire une sorte de "double double-dispatch" où il suffierait juste de créer sa classe et de définir uniquement les méthodes pour les Types où nous voulons un traitement particulier exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Visiteur
    {
                public : 
                            virtual void visite(Visitable &);
     
    }
     
    class VisiteurFils : public Visiteur
    {
                 public :
                             virtual void visite(Visitable &);
                             virtual void visite(VisitableFils &);
    }

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut

    En fait, le patron visiteur n'est qu'une mise en oeuvre parmi d'autre du principe du double dispatch...

    Tu peux donc envisager un nombre tout à fait illimité de solutions qui te seraient propres

    Par exemple, pour rester dans le contexte d'un visiteur, tu peux parfaitement envisager le visiteur "asynchrone", qui va tenter de transtyper la classe de base "visiteur" dans un de ses types dérivés, sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    class Visiteur
    {
        public:
            /* pour les types que l'on connait déjà */
            virtual void visit(Derivee1 /* const */ &);
            virtual void visit(Derivee2 /* const */ &);
            /* ...*/
    };
    class AutreVisiteur : public Visiteur
    {
        public:
            /* cette fonction ci fait partie d'un ajout suite à évolution */
            virtual void visit(NouvelleDerivee /* const */ &);
    };
    class NouvelleDerivee : public Base
    {
         public:
             virtual void accept( Visiteur & v)
             {
                  AutreVisiteur * reel = dynamic_cast<AutreVisteur *> (&v);
                  if(reel)
                  {
                      reel->visit(*this);
                  }
             } 
    };
    Mais tu peux aussi t'éloigner du concept visiteur et utiliser le double dispatch "pur et simple", sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    class Base
    {
        public:
            virtual void foo() = 0;
    }
    class Derivee : public Base
    {
        public:
            virtual void foo() { bar(*this);}
    };
    class AutreDerivee : public Base
    {
        public:
            virtual void foo() {   doSomething(*this);}
    };
    class TroisiemeDerivee : public Base
    {
        public:
            /* voir avec un objet connu */
            virtual void foo() 
            {  
                UnTypeQuelconque obj; 
                obj.doSomething(*this);
            }
    };
    Les limites du système étant celles de ta propre imagination

    Ceci dit, le principe ouvert fermé devrait, effectivement, t'inciter à envisager une solution proche du visiteur asynchrone si tu viens à devoir rajouter un type au niveau des visitables, de manière à garder les visiteurs "de base" (ceux qui n'avaient pas prévus cette évolution) "aussi stables que possibles"
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Le visiteur acyclique est aussi une solution, proche de celle proposée par koala01. (Ne pas chercher à aller sur le site objectmentor.com - il est mort depuis déjà quelques mois - RC Martin est passé à autre chose )
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

Discussions similaires

  1. Design pattern Visitor & double dispatching
    Par f56bre dans le forum Langage
    Réponses: 5
    Dernier message: 24/03/2010, 11h22
  2. [Visiteur] design pattern visiteur
    Par wsdl_adr dans le forum Design Patterns
    Réponses: 1
    Dernier message: 07/10/2008, 20h41
  3. [Visiteur] comment utiliser le design pattern de visiteur pour créer un compilateur
    Par katimm dans le forum Design Patterns
    Réponses: 12
    Dernier message: 18/09/2008, 10h22
  4. [Visiteur] design pattern Visiteur ou Iterateur pour parcourir une arborescence?
    Par mehdiing dans le forum Design Patterns
    Réponses: 1
    Dernier message: 29/05/2008, 17h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo