28 votes

Différence entre le modèle de visiteur et la double répartition

Je lis sur le modèle de visiteur, et il ressemble à Double Dispatch. Y a-t-il une différence entre les deux. Faire les deux termes signifie la même chose.

référence: http://www.vincehuston.org/dp/visitor.html

27voto

Emilio Garavaglia Points 9189

En bref

ils viennent de différentes conceptualisations que, dans certaines langues, où la double expédition n'est pas pris en charge nativement, de plomb pour le modèle visiteur comme un moyen pour concaténer deux (ou plus) d'une seule expédition afin d'avoir un multi-envoi de substitution.

Dans la longue

L'idée de la répartition multiple est - essentiellement - de permettre à un appel comme

void fn(virtual base_a*, virtual base_b*); (note: non pas comme un membre de la classe: ce n'est PAS le C++! )

qui peut être remplacée que

void fn(virtual derived_a1*, virtual derived_b1*);
void fn(virtual derived_a2*, virtual derived_b1*);
void fn(virtual derived_a1*, virtual derived_b2*);
void fn(virtual derived_a2*, virtual derived_b2*);

de sorte que, lors de l'appel

fn(pa, pb)

l'appel est redirigé vers le remplacer qui correspond au runtime type de tant pa et pb. (Vous pouvez généraliser ce quel que soit le nombre de paramètres)

Dans un langage comme C++, C#, Java, ce mécanisme n'existe pas d'exécution et de type d'expédition fonctionne essentiellement avec un seul paramètre (qui, n'étant que l'une est faite de manière implicite dans la fonction au moyen de la fonction elle-même membre de la classe:

en d'autres termes, le pseudo-code

void fn(virtual base_a*, base_b*) 

devient le réel (C++)

class base_a
{
public:
    virtual void fn(base_b*);
}

Notez qu'ici, il n'y a pas de plus virtual face base_b, qu'à partir de maintenant est statique. Un appel comme

pa->fn(pb) si pa de points pour un derived_a2 et pb pour un derived_b1 sera envoyé à derived_a2::fn(base_b*), peu importe s'il ya un derived_a2::fn(derived_b1*) y: run-time type de l'objet pointé par le pb n'est pas pris en compte.

L'idée de le visiteur formulation est ce que vous appelez le virtuel envoi d'un objet qui appelle (finalement) le virtuel envoi de l'autre:

class base_a
{
public:
   virtual void fn(base_b*)=0;
   virtual void on_visit(derived_b1*)=0;
   virtual void on_visit(derived_b2*)=0;
}

class base_b
{
public:
   virtual void on_call(derived_a1*)=0;
   virtual void on_call(derived_a2*)=0;
}

class derived_a1: public base_a
{
public:
   virtual void fn(base_b* pb) { pb->on_call(this); }
   virtual void on_visit(derived_b1* p1) { /* useful stuff */ }
   ...
}

class derived_b1: public base_b
{
public:
  virtual void on_call(derived_a1* pa1) { pa1->on_visit(this); }
  ... 
};

maintenant, un appel comme pa->fn(pb), si pa de points à derived_a1 et pb pour derived_b1, va enfin aller à l' derived_a1::on_visit(derived_b1*).

8voto

Nawaz Points 148870

Modèle visiteur est une solution qui implémente le comportement de la double expédition. Il peut y avoir plusieurs autres solutions. Le terme double expédition elle-même ne donne aucune idée de la solution, en fait c'est un problème dont la solution est fournie par des habitudes des visiteurs.

En C# (4.0), on peut utiliser dynamic mot-clé pour mettre en œuvre la double répartition, auquel cas le modèle visiteur n'est pas nécessaire. Voici ma solution pour double-dispatch problème à l'aide d' dynamic mot-clé:

5voto

Matthieu M. Points 101624

Répartition dynamique se réfère à la notion de l'envoi d'une méthode basée sur les informations d'exécution, en général. La plupart OO des systèmes (comme en Java/C#/C++) généralement de mettre en œuvre la distribution dynamique via virtual méthodes (si pas toutes les méthodes sont virtuelles dépendent de la langue); cette limite à l'expédition selon une méthode unique argument (l'objet implicite de référence).

En général, vous pourriez souhaiter pour l'expédition en fonction d'un nombre arbitraire d'éléments. Double Expédition, par exemple, est la nécessité/possibilité d'envoi en fonction de deux arguments de la méthode.

D'autre part, le Modèle Visiteur est une mise en œuvre de Multi Envoi en général et, donc, en Double Expédition, en particulier, dans de tels OO des systèmes.

3voto

James Kanze Points 96599

La double expédition est un problème technique qui peut, selon la langue, être résolu de différentes manières - certaines langues prennent directement en charge la double expédition. Le modèle de visiteur est un modèle qui peut être utilisé pour résoudre différents problèmes. Dans le cas de C ++, c'est la solution la plus fréquente (mais pas la seule) utilisée pour la double répartition, mais elle n'est pas utilisée exclusivement pour cela, et elle peut être utile même dans les langages qui prennent en charge la double répartition.

1voto

Peter Wood Points 4536

De Wikipedia:

le visiteur modèle simule double expédition dans une classique de répartition unique langage orienté objet comme Java, Smalltalk et C++.

Aussi à partir de Wikipédia:

Le problème décrit ci-dessus peut être résolu par la simulation de double expédition, par exemple à l'aide d'un modèle visiteur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X