Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2605 connectés 

  FORUM HardWare.fr
  Programmation
  C#/.NET managed

  Pattern Visiteur et Decorateur

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Pattern Visiteur et Decorateur

n°1561565
vonm
Posté le 17-05-2007 à 12:49:09  profilanswer
 

Bonjour,
 
j'utilise actuellement une bibliotheque qui a une fonction qui me renvoie une liste d'objets (XObj1, XObj2 qui derivent tous de XObj).
 
J'aimerais afficher cette liste en faisant un traitement different en fonction du type d'objet.
 
Pour cela, je souhaiterais utiliser un visiteur qui me parait la solution la plus souple.
 
Malheureusement, je ne peux modifier le code des objetx Xobj, Xobj1 Xobj2.
J'ai donc pensé a faire un decorateur qui dont voici le code :
 
class XObjectDecorator
{
private XObj _wow = null;
 
public XObjectDecorator(XObj w)
{
this._wow = w;
}
 
public void Accept(IVisitor v)
{
v.Visit(this._wow);
}
}
 
que j'utiliserais comme ceci :
ConcreteVisitor visit = new ConcreteVisitor();
new XObjectDecorator(gList.Object(i)).Accept(visit);
 
Malheureusement, a la compilation j'ai l'erreur suivant sur v.visit(this._wow) :
 
Erreur 1 La méthode surchargée correspondant le mieux à 'IVisitor.Visit(XObj1)' possède des arguments non valides
Erreur 2 Argument '1' : impossible de convertir de 'XObj' en 'XObj1'
 
Je ne vois pas du tout ce qui ne va pas.
 
Auriez-vous une idee ?
 
merci d'avance
 
v.

mood
Publicité
Posté le 17-05-2007 à 12:49:09  profilanswer
 

n°1561844
MagicBuzz
Posté le 18-05-2007 à 01:08:24  profilanswer
 

J'ai rien pigé [:cerveau foudtag]
 
C'est quoi ces histoires de visiteurs et décorateur ?
Et pourquoi t'as un visiteur en béton ? (concrete chez moi ça veut dire béton en anglais :o)

n°1561847
zapan666
Tout est relatif
Posté le 18-05-2007 à 01:14:41  profilanswer
 

MagicBuzz a écrit :

J'ai rien pigé [:cerveau foudtag]

 

C'est quoi ces histoires de visiteurs et décorateur ?
Et pourquoi t'as un visiteur en béton ? (concrete chez moi ça veut dire béton en anglais :o)


 [:totoz]

 

-------

 

IVisitor à une méthode Visit(XObj) ? (w doi être XObj et pas XObj1 ou 2 non ?) (verifie via le debugueur - bref, c'est quoi les types des objets qui sont dans ta listes)

 

Par contre, ce qui m'étonne, c'est que ton décorateur n'hérite pas de XObj (et en quoi il décore, en fait ?)

 


(je supose que XObj1 et 2 hérite de XObj)

  


Message édité par zapan666 le 18-05-2007 à 01:26:04

---------------
my flick r - Just Tab it !
n°1561857
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 18-05-2007 à 02:41:44  profilanswer
 

MagicBuzz a écrit :

J'ai rien pigé [:cerveau foudtag]
 
C'est quoi ces histoires de visiteurs et décorateur ?
Et pourquoi t'as un visiteur en béton ? (concrete chez moi ça veut dire béton en anglais :o)


je pense que la lecture de ce bouquin s'impose : http://www.amazon.fr/Design-patter [...] 2841773507

n°1561895
MagicBuzz
Posté le 18-05-2007 à 10:23:07  profilanswer
 

Y'a une version PDF gratuite ?

n°1561915
MagicBuzz
Posté le 18-05-2007 à 11:06:21  profilanswer
 

Ben si ça va pas chercher plus loin que ça, y'a pas besoin d'acheter un bouquin à 56 € pour savoir ce que c'est.
http://en.wikipedia.org/wiki/Visitor_pattern
http://en.wikipedia.org/wiki/Double_dispatch
http://www.exciton.cs.rice.edu/Jav [...] attern.htm
 
http://nice.sourceforge.net/visitor.html
=> Le dernier lien semble contredire la conclusion du second non ? Lequel est dans le vrai dans cas du C# ? Notamment, l'exemple de l'utilité du double dispatching s'applique au C++ qui est présenté dans l'exemple ayant des lacunes du point de vue de la gestion des surcharges. Qu'en est-il avec le C# ? Parceque moi je trouve aussi que simplement dériver tous mes objets de la même interface est une solution plus propre et surtout, moins chiante à coder/relire (le code est dans la classe, pas dans une classe qui n'a rien à voir et qu'on n'atteind qu'à force d'appels récursifs)

Message cité 1 fois
Message édité par MagicBuzz le 18-05-2007 à 11:08:17
n°1561951
zapan666
Tout est relatif
Posté le 18-05-2007 à 11:50:24  profilanswer
 

MagicBuzz a écrit :

(le code est dans la classe, pas dans une classe qui n'a rien à voir et qu'on n'atteind qu'à force d'appels récursifs)


Si ta modélisation est mal foutu, forcement, ça n'aide pas.
si tu attaque la classe parente de ta classe parente, il y a un problème.


---------------
my flick r - Just Tab it !
n°1561968
MagicBuzz
Posté le 18-05-2007 à 12:07:02  profilanswer
 

:heink:
 
Ben non. Regarde l'exemple du premier lien.
 
Le code relatif à l'affichage de "Car", "Wheel" et autres se trouve non pas dans les classes en question, mais dans le visiteur (PrintVisitor) au lieu d'être dans chacune des classes.
 
Pour moi, il serait plus judicieux de faire une interface IPrintable, contenant "Print()" et en faire hériter toutes les classes en question.
=> Ainsi, le code relatif à l'impression sont directement dans les objets plutôt que dans un objet qui y fait référence, et qui est appelé par ces objets en question.
 
Bon, l'exemple est très succint, et il y a certainement des cas où l'intérêt est réel, mais là je vois pas trop.
 
Le seul intérêt à mes yeux est celui annoncé au départ : si on veut modifier le comportement de "Print()" on peut n'a pas besoin de modifier les objets "parents", tout le code relatif à l'impression se trouve dans la même classe. Mais bon, avec la clause "partial", on peut parfaitement en C# regrouper tout le code relatif à l'impression de tous les objets dans un fichier dédié, donc ensuite l'intérêt me semble assez maigre.
 
Le second intérêt (mais est-ce un intérêt) c'est que les objets "parents" ne fond plus de références croisés entre eux, c'est la class visteur qui s'en charge. Mais à nouveau, à quoi ça sert ? (dans l'exemple de la classe Car, il fait de toute façon déjà références aux autres objets...)

Message cité 1 fois
Message édité par MagicBuzz le 18-05-2007 à 12:12:10
n°1561975
zapan666
Tout est relatif
Posté le 18-05-2007 à 12:16:11  profilanswer
 


non mais en fait, j'ai compris que tu faisais quelque chose genre

Code :
  1. super.super.super.super.super.doIt()


 J'ai eux peur [:cupra]  
 

MagicBuzz a écrit :


Le code relatif à l'affichage de "Car", "Wheel" et autres se trouve non pas dans les classes en question, mais dans le visiteur (PrintVisitor) au lieu d'être dans chacune des classes.


Si il veut changer la méthode d'affichage des objets (en envoyant tout dans la sortie d'erreur par exemple), il n'a que le visiteur à modifier et pas toutes les classes Car, Wheel, etc.
 
Et en allant plus loin, si la personne implemente un adaptateur dans le visiteur, selon que tu sois en Debug ou Release par exemple, le programme peut sortir les informations soit sur la sortie standard (debug) soit dans un buffer (Release par exemple) ce qui n'est pas possible si tu mets ce code dans les classes Car, etc à moins de forcer ça quelque part.
 
(l'adaptateur va faire le choix selon la situation Debug ou Release)


---------------
my flick r - Just Tab it !
n°1561982
MagicBuzz
Posté le 18-05-2007 à 12:26:14  profilanswer
 

Ben moi dans ces cas, je fais une classe "Afficheur", et c'est lui qui s'occupe de faire ça proprement. Mais c'est les objets eux-même qui lui disent quoi afficher.
 
Ceci dit, je comprends parfaitement ton explication en ce qui concerne un changement de comportement de l'affichage pour toutes les méthodes d'un coup.
Mais dans ce cas, je te renvois à la clause "partial", qui permet de pallier à un certain nombre de problèmes sans problème.
 
(Bon, pas complètement, genre si "Visitor" contiens aussi des méthodes privées partagées entre tous les Print(), je suis d'accord que là c'est baisé si tu ne passes pas par cette structure :jap:

mood
Publicité
Posté le 18-05-2007 à 12:26:14  profilanswer
 

n°1561987
zapan666
Tout est relatif
Posté le 18-05-2007 à 12:30:52  profilanswer
 

MagicBuzz a écrit :


Mais dans ce cas, je te renvois à la clause "partial", qui permet de pallier à un certain nombre de problèmes sans problème.


 [:cupra] J'ai jamais fais de C#


---------------
my flick r - Just Tab it !
n°1562018
MagicBuzz
Posté le 18-05-2007 à 13:22:36  profilanswer
 

Ben partial, ça sert juste à dire "ce petit bout de code en fait, c'est un morceau de ma classe untel". Je pense qu'on a la même chose en Java.
 
Exemple :
 
interfaces.cs

Code :
  1. namespace TstPrint
  2. {
  3.    public interface IPrintable
  4.    {
  5.        void Print();
  6.    }
  7.  
  8.    public interface ITruc
  9.    {
  10.        void Truc();
  11.    }
  12. }


 
voiture.cs

Code :
  1. namespace TstPrint
  2. {
  3.    public partial class Voiture : IPrintable, ITruc
  4.    {
  5.        private string nom;
  6.        private Roue[] roues;
  7.        private Couleur couleur;
  8.        private IPrintable[] allPrintableMembers = new IPrintable[5];
  9.        
  10.        public Voiture(string Nom, float RadiusRoues)
  11.        {
  12.            this.nom = Nom;
  13.            this.couleur = new Couleur("Verte" );
  14.            this.allPrintableMembers[4] = this.couleur;
  15.            this.roues = new Roue[4];
  16.            for (int i = 0; i < 4; i++)
  17.            {
  18.                this.roues[i] = new Roue(i, RadiusRoues);
  19.                this.allPrintableMembers[i] = this.roues[i];
  20.            }
  21.        }
  22.  
  23.        public string GetName()
  24.        {
  25.            return this.nom;
  26.        }
  27.    }
  28. }


 
Roue.cs

Code :
  1. namespace TstPrint
  2. {
  3.    public partial class Roue : IPrintable, ITruc
  4.    {
  5.        private int position;
  6.        private float radius;
  7.  
  8.        public Roue(int Position, float Radius)
  9.        {
  10.            this.position = Position;
  11.            this.radius = Radius;
  12.        }
  13.  
  14.        public float GetRadius()
  15.        {
  16.            return this.radius;
  17.        }
  18.    }
  19. }


 
couleur.cs

Code :
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4.  
  5. namespace TstPrint
  6. {
  7.    public partial class Couleur : IPrintable
  8.    {
  9.        string couleur;
  10.  
  11.        public Couleur(string Color)
  12.        {
  13.            this.couleur = Color;
  14.        }
  15.  
  16.        public string GetCouleur()
  17.        {
  18.            return couleur;
  19.        }
  20.    }
  21. }


 
print.cs

Code :
  1. using System;
  2.  
  3. namespace TstPrint
  4. {
  5.    public partial class Voiture
  6.    {
  7.        public void Print()
  8.        {
  9.            Console.WriteLine("Voiture : " + this.GetName());
  10.  
  11.            foreach (IPrintable printableObject in this.allPrintableMembers)
  12.            {
  13.                printableObject.Print();
  14.            }
  15.        }
  16.    }
  17.  
  18.    public partial class Roue
  19.    {
  20.        public void Print()
  21.        {
  22.            Console.WriteLine("Roue " + this.position.ToString() + " : " + this.GetRadius() + " pouces" );
  23.        }
  24.    }
  25.  
  26.    public partial class Couleur
  27.    {
  28.        public void Print()
  29.        {
  30.            Console.WriteLine("Couleur : " + this.GetCouleur()););
  31.        }
  32.    }
  33. }


 
truc.cs

Code :
  1. namespace TstPrint
  2. {
  3.     public partial class Voiture
  4.     {
  5.         public void Truc()
  6.         {
  7.             this.nom = this.nom.Substring(0, 3);
  8.             for (int i = 0; i < 4; i++)
  9.             {
  10.                 this.roues[i].Truc();
  11.             }
  12.         }
  13.     }
  14.     public partial class Roue
  15.     {
  16.         public void Truc()
  17.         {
  18.             this.radius /= 2f;
  19.         }
  20.     }
  21. }


 
program.cs

Code :
  1. using System;
  2.  
  3. namespace TstPrint
  4. {
  5.    class Program
  6.    {
  7.        static void Main(string[] args)
  8.        {
  9.            Voiture v = new Voiture("Laguna", 8.2f);
  10.            v.Print();
  11.            Console.WriteLine("-----------" );
  12.            v.Truc();
  13.            v.Print();
  14.            Console.ReadKey();
  15.        }
  16.    }
  17. }


 
Sortie :


Voiture : Laguna
Roue 0 : 8,2 pouces
Roue 1 : 8,2 pouces
Roue 2 : 8,2 pouces
Roue 3 : 8,2 pouces
Couleur : Verte
-----------
Voiture : Lag
Roue 0 : 4,1 pouces
Roue 1 : 4,1 pouces
Roue 2 : 4,1 pouces
Roue 3 : 4,1 pouces
Couleur : Verte


 
=> On voit dans cet exemple que tout ce qui est relatif à l'impression se situe dans le fichier "print.cs", alors que les méthodes d'affichage restent bel et bien dans les objets finaux.
 
-- Edit : Version corrigée avec un exemple qui marche ;)
-- Edit² : Et plus complet :D


Message édité par MagicBuzz le 18-05-2007 à 13:50:08
n°1562461
vonm
Posté le 19-05-2007 à 20:42:46  profilanswer
 

alors la ca m'interesse.
je ne connaissais pas le mot cle partial (c# 2 ?)
puis-je de cette maniere completer une classe que je n'ai pas ecrite ?
cad une classe qui se trouverait dans un framework qualconque ?
 
si oui, alors il me suffit de rajouter une methode d'acceptation de mon visiteur dans les classes issues de la bibliotheque que j'utilise (un decorateur qui ne dis pas son nom quoi !)
 
Edit:
 
bon a priori je me suis affole pour rien, ca ne fonctionne pas.
etant donne que je n'ai pas la main sur les objets de la bibliotheque je ne peux pas leur rajouter de comportement en utilisant partial.


Message édité par vonm le 19-05-2007 à 20:49:57
n°1562568
moi23372
Posté le 20-05-2007 à 11:38:33  profilanswer
 

il faut que les classes initiales soit dotée du mot clé partial.  
 
Maintenant pour en revenir à son utilisation, ça doit être utilisé pour séparer le code d'une classe dans plusieurs fichiers. Si c'est pour complété tes objets, autant en dérivé et complété dans la classe fille.  
 
oui PARTIAL est arrivé avec .NET 2.0

n°1562770
MagicBuzz
Posté le 21-05-2007 à 09:27:06  profilanswer
 

Je tiens à souligner que si "partial" part d'une très bonne idée, on remarque dans mon exemple plusieurs choses :
- Pour indiquer de quoi dérive une classe, il suffit d'indiquer les classes "parentes" dans un seul fichier. Je n'ai pas testé les mélanges, mais avec un peu de pas de chance, ça marche (genre dans un fichier, je dérive d'une interface, et dans un autre fichier, d'une autre). Dans ce cas, on remarque rapidement les problèmes de maintenance que cela peut impliquer...
- Partial peut être utilisé comme dans mon exemple, pour regrouper dans un même fichier toutes les surcharges de différentes classes dérivées d'une même interface, de façon à retrouver facilement le code. Le problème, c'est que rapidement ça peut se bordeliser, si une personne qui intervient sur le projet ne suit pas cette façon de "ranger" le code. Idem si un fichier servait à contenir les méthodes "métier" d'une classe. Si on ne suis pas la règle, on peut rapidement arriver à du code difficile à relire.
- L'implémentation "de base" en C# consiste à mettre dans un fichier spécial toute "l'initialisation" et "le design" des form dans un fichier, tandis que le code utilisateur se trouve dans un autre fichier. A nouveau, si le code "utilisateur" se met à faire de l'inisitlisation -notamment, on y trouve le constructeur- ou du design (présente de la méthode onpaint par exemple) on peut arriver à une lisibilitée très amoindrie : mais d'où vient cet objet ? il est initialisé comment ? et qu'est-ce qu'il fout ici au milieu de ma form ? etc.
 
Bref, à utiliser en faisant attention. En soit il peut être très pratique et utile, mais aussi s'avérer l'enemi juré de la maintenabilité du code, surtout si on n'utilise pas de GUI évoluée.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C#/.NET managed

  Pattern Visiteur et Decorateur

 

Sujets relatifs
[PHP] preg_replace - Question sur la capture d'un pattern - EfficacitéLe visiteur choisi le fond du site!!!
Savoir si un visiteur n'est plus sur le siteJLabel dans un pattern MVC
nombre de visiteur sur un siteIntégrer l'heure MAIS PAS celle inscrit sur le PC visiteur
Détecter le pays du visiteur et mettre la rédirection adéquateFont et CSS : que faire quand le visiteur n'a pas la typo utilisée ?
afficher l'ip du visiteur du site :[resolu] Conflit Virtuel Static ( Factory Design Pattern )
Plus de sujets relatifs à : Pattern Visiteur et Decorateur


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)