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

Langage C++ Discussion :

Design pattern Visitor & double dispatching


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 199
    Par défaut Design pattern Visitor & double dispatching
    Bonjour,

    J'ai besoin de mettre en place une architecture qui m'oriente vers le design pattern Visitor (ie : ensemble de classes "noyau" et de nouvelles opérations à réaliser sur ces classes sans les polluer).

    La question que je me pose est l'utilité de la méthode "Accept()" et du double dispatching dans ce cas?

    Par exemple j'ai un ensemble de classes classe1, classe2, etc. sur lesquelles viendront agir les visiteurs Visitor1, Visitor2, etc.
    Le livre du GOF propose une implémentation permettant d'utiliser le pattern ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    classe1* maclasse;
    visitor1 visitor;
    maclasse->accept(visitor);
    Cette dernière ligne conduira à appeler une fonction "visit()" du visiteur qui fera le job.

    Je me demande pourquoi ne procède t'on pas directement ainsi comme suit?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    visitor.visit(maclasse);
    D'avance merci de m'éclairer. J'ai sans doute loupé quelque chose dans la logique du pattern et dans ses cas d'application.

  2. #2
    Membre Expert
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Par défaut
    Citation Envoyé par f56bre Voir le message
    Je me demande pourquoi ne procède t'on pas directement ainsi comme suit?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    visitor.visit(maclasse);
    Cela impliquerait de surchargé Visitor::visit pour toutes nouvelles classes pouvant acceptés un Visitor.

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Le principe du double dispatch et du visiteur doit se comprendre lorsqu'on désire 'descendre' simultanément 2 hiérarchies. accept permet d'atteindre l'élément concret idoine et visit sur celui du visiteur concret.
    En fait, l'idée est que le conteneur ne connait pas le visiteur concret ni l'élément concret, mais n'est lié qu'avec leur classe de base (avec l'héritage ou une classe template supposée avoir la bonne fonction). Le double dispatch permet ainsi de descendre dans les 2 hiérarchies, ce que ne permettrait pas ta solution.
    @Joel : c'est déjà le cas du pattern tel que présenté par le GoF et c'est un gros inconvénient de ce pattern. Cet inconvénient (et repris dans l'article cité plus bas) est précisé dans le GoF qui dit bien que la structure des types à visiter doit être stable sinon ça implique beaucoup de changement de code côté visiteur.
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    #include <iostream>
    struct visitor;
    struct element
    {
        virtual void accept(visitor const&)=0;
        virtual ~element(){}
    };
     
    struct element_1;
    struct element_2;
     
    struct visitor
    {
        virtual void visit_element_1(element_1 const&)const=0;
        virtual void visit_element_2(element_2 const&)const=0;
        virtual ~visitor(){}
    };
     
    struct element_1 : public element
    {
        virtual void accept(visitor const&v_)
        {
            v_.visit_element_1(*this);
        }
    };
     
    struct element_2 : public element
    {
        virtual void accept(visitor const&v_)
        {
            v_.visit_element_2(*this);
        }
    };
     
    struct visitor_concret : public visitor
    {
        virtual void visit_element_1(element_1 const&)const
        {
            std::cout<<"visit d'un element 1\n";
        }
        virtual void visit_element_2(element_2 const&)const
        {
            std::cout<<"visit d'un element 2\n";
        }
    };
     
    #include <vector>
    #include <boost/shared_ptr.hpp>
    struct conteneur
    {
        conteneur()
        {
            mes_elements.push_back(boost::shared_ptr<element>(new element_1));
            mes_elements.push_back(boost::shared_ptr<element>(new element_2));
        }
     
        void visit(visitor const &v_) const
        {
            typedef std::vector<boost::shared_ptr<element> >::const_iterator iterator;
            for(iterator it=mes_elements.begin();it!=mes_elements.end();++it)
            {
                (*it)->accept(v_);
            }
        }
     
        private:
        conteneur(conteneur const&);
        conteneur&operator=(conteneur);
        private:
        std::vector<boost::shared_ptr<element> > mes_elements;
    };
     
    int main()
    {
        conteneur c;
        c.visit(visitor_concret());
        return 0;
    }
    Une lecture intéressante : V comme visiteur, de Deloget.

  4. #4
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    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
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Une lecture intéressante : V comme visiteur, de Deloget.
    Ah, et moi qui allais intervenir dans la discussion...
    [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.

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut Emmanuel,
    Citation Envoyé par Emmanuel Deloget Voir le message
    Ah, et moi qui allais intervenir dans la discussion...
    C'est clairement un article intéressant dès que l'on parle de visiteur.
    Ceci dit, j'ai récemment relu la partie consacrée aux visiteurs du DP des GoF. Et quelque part, il me semble qu'ils étaient conscients du problème. Ils disent bien que le DP visiteur, du fait de l'absence de double dispatch, n'est à mettre en œuvre que lorsque la structure des objets à visiter sont stables. Donc, à priori, qu'il n'y a pas de nouveaux types d'objets à rajouter. Ce qui revient à dire que l'interface du visiteur abstrait doit être stable. Donc, la limite était bien perçue et expliquée dans le bouquin.

  6. #6
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    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
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Salut Emmanuel,
    C'est clairement un article intéressant dès que l'on parle de visiteur.
    Ceci dit, j'ai récemment relu la partie consacrée aux visiteurs du DP des GoF. Et quelque part, il me semble qu'ils étaient conscients du problème. Ils disent bien que le DP visiteur, du fait de l'absence de double dispatch, n'est à mettre en œuvre que lorsque la structure des objets à visiter sont stables. Donc, à priori, qu'il n'y a pas de nouveaux types d'objets à rajouter. Ce qui revient à dire que l'interface du visiteur abstrait doit être stable. Donc, la limite était bien perçue et expliquée dans le bouquin.
    'Zact. Ca fait longtemps que je ne l'ai pas ouvert moi-même. Ceci dit, cette limitation est étonnamment restrictive étant donné la nature même du pattern visiteur (le fait de l'intégrer dans une hiérarchie de classe suppose que cette hiérarchie est ouverte à l'extension, hors le pattern lui même ne l'est pas).

    Le visiteur acyclique de R.C.Martin est (selon moi) à conseiller - d'autant plus qu'il n'a pas plus de problèmes de performance qu'un système ou le multi-dispatch serait implémenté nativement puisque les décisions de dispatch liées au type dynamique sont nécessairement prise au runtime, ce qui est émulé grâce au dynamic_cast<>).

    Ceci dit, c'est mon opinion

    Un cas très intéressant d'application du pattern version GoF est le cas ou les instances à visiter sont définies à l'extérieur de l'application, par exemple par des scripts. Dans ce cas, la hiérarchie qui doit être visitée par les différents visiteurs est définie au préalable sans pour autant que cela n'empêche de l'étendre. Mais ça reste quand même un cas particulier qui, en pratique, reste rare.
    [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. Réponses: 2
    Dernier message: 18/01/2013, 22h36
  2. Problème avec le design pattern visitor
    Par RT222 dans le forum Langage
    Réponses: 5
    Dernier message: 13/05/2012, 20h28
  3. Design Pattern Visitor et Decorateur
    Par deubelte dans le forum C++
    Réponses: 8
    Dernier message: 20/05/2010, 18h05
  4. [GOF] quel design pattern: Visitor, Strategy ou commande???
    Par smartCoder dans le forum Design Patterns
    Réponses: 4
    Dernier message: 15/01/2008, 14h10
  5. [Curiosité] design pattern visitor et compilation
    Par krokmitaine dans le forum C++
    Réponses: 6
    Dernier message: 10/11/2006, 15h06

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