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 :

Heritage et pb de conception


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 37
    Points : 19
    Points
    19
    Par défaut Heritage et pb de conception
    Bonjour,

    je suis en phase d'analyse pour un petit projet et je bloque sur quelque chose qui doit etre simple je pense mais qui m'echappe (Je reviens au langage objet que j'avais quitté depuis un moment).

    Pour resumer, je défini une classe mère qui représente une structure de données qui seront chargées a partir d'un fichier tabulaire.
    Cependant, il existe deux types de fichiers, un contenant beaucoup plus d'informations que l'autre.

    J'ai donc défini dans ma classe mere les traitement communs aux deux types de fichiers ainsi que la declaration de la fonction virtuelle de lecture du fichier (apres reflexion je ne pense pas qu'il soit necessaire qu'elle soit virtuelle mais plutot uniquement dans les classes filles mais c'est un autre debat).

    J'ai ensuite des classes filles qui heritent de cette premiere classe, l'une (pour le fichier ayant peu d'informations) apportant peu ou pas de fonctions specifiques et l'autre pour le fichier plus complet permettant de prendre en compte les informations supplementaires.
    Le but de ces traitements supplementaires sera de filtrer certaines lignes du fichiers lu en fonction d'une autre colonne du fichier par exemple.


    En bref, je dois pouvoir gerer dans une liste (un vector par exemple) les données de classes filles (peu importe qu'elles viennent d'un type de fichier ou de l'autre) et les presenter a l'utilisateur par le biais de l'interface graphique (QT mais ce n'est pas forcement important)
    Je comptais donc faire un vector de pointeurs vers la classe mere et le parcourir pour afficher les infos necessaire.
    On arrive enfin au coeur de ma question, j'aimerais, lorsque je presente la liste de ces objets pouvoir differencier si ils appartiennent a l'une ou l'autre des classes filles, pour proposer a l'utilisateur d'appuyer sur un bouton qui fera le traitement specifique adequat a chaque type.
    Je ne vois pas comment faire cela sans appel a des fonctions speciales du langage qui stockent le type de la classe mais ca ne me plait guere (je ne trouve pas ca tres propre) et je soupçonne un defaut dans la conception du probleme.

    Si vous aviez une idée ou une piste a suivre pour la base de mon schema ce serait super.

    merci de votre aide.

    Cordialement.

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 37
    Points : 19
    Points
    19
    Par défaut
    Pour etre plus clair, j'aimerais que le bouton "filtrer" soit present a coté des objets de ma liste qui ont été chargés a partir d'un fichier qui a toutes les infos et qu'il soit grisé pour ceux chargés a partir des fichiers minimalistes.

  3. #3
    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,

    La première question que tu devrais te poser est
    Vais-je effectivement manipuler des objets apportant peu ou pas de fonctionnalités supplémentaires et des objets en apportant d'avantage en même temps
    A priori, je dirais que, si tu manipule les deux types ensemble, tu n'aura finalement que faire de savoir si ton objet apporte ou non un grand nombre de fonctionnalités supplémentaires: tu ne les utilisera qu'au travers de leur interface commune avec la classe de base

    De même, il est raisonnable de penser que, si tu décide de travailler sur des objets "plus complexes", tu aura pris soin... d'écarter tous les objets les moins complexes

    Maintenant, si tu veux, quoi qu'il advienne, être en mesure de gérer les objets "les plus complexes" et les objets "les plus simples" en tant que tels, rien ne vaut le DP visiteur

    Il permettra en effet, non seulement d'appliquer le bon traitement au bon objet, mais, en plus, il te permettra d'envisager de nouvelles sortes de traitement

    Cela se traduirait en code 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
    27
    28
    class SimpleObject;
    class ComplexObject;
    /* une classe de base, qui ne demande qu'à être spécialisée en fonction
     * des besoins :-D
     */
    class AbstractVisitor
    {
        public:
            virtual void visit(SimpleObject /* const */ &) = 0;
            virtual void visit(ComplexObject /* const & */ ) =0;
    };
    class ConcreteVisitor : public AbstractVisitor
    {
     
            virtual void visit(SimpleObject /* const */ &) ;
            virtual void visit(ComplexObject /* const & */ );
    };
    void ConcreteVisitor::visit(SimpleObject /* const */ &)
    {
        /* traitement adapté aux objets les plus simples */
    }
    void ConcreteVisitor::visit(ComplexObject/* const */ &)
    {
        /* traitement adapté aux objets les plus complexes*/
    }
    /* Tu peux créer autant de visiteurs dérivant de AbstractVisitor que
     * de type de traitement différents que tu souhaite entreprendre ;-)
     */
    et, pour ce qui est de tes classes "utiles", elles ressembleraient à
    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
    class Base
    {
        public:
            /* pour pouvoir les détruire correctement lorsque l'on n'en a plus 
             * besoin
             */
            virtual ~Base();
            /* pour pouvoir appliquer le "double dispatch" qui nous permettra
             * de gérer les objets selon leur type dynamique
             */
           virtual void accept(AbstractVisitor  /* const */ & ) /* const */= 0;
    };
    Base::~Base(){/* ce qui doit être fait */}
    class SimpleObject : public Base
    {
        public:
            /* pour pouvoir les détruire correctement lorsque l'on n'en a plus 
             * besoin
             */
            virtual ~Base();
            /* pour pouvoir appliquer le "double dispatch" qui nous permettra
             * de gérer les objets selon leur type dynamique
             */
           virtual void accept(AbstractVisitor  /* const */ & )  /* const */;
    }
    void SimpleObject::accept(AbstractVisitor  /* const */ & v) /* const */
    {
        /* fait appel à AbstractVisitor::visit(SimpleObject /* const */ &) */
       v.visit(*this);
    }
    class ComplexObject: public Base
    {
        public:
            /* pour pouvoir les détruire correctement lorsque l'on n'en a plus 
             * besoin
             */
            virtual ~Base();
            /* pour pouvoir appliquer le "double dispatch" qui nous permettra
             * de gérer les objets selon leur type dynamique
             */
           virtual void accept(AbstractVisitor  /* const */ & )  /* const */;
    };
    void ComplexObject::accept(AbstractVisitor  /* const */ & v) /* const */
    {
        /* fait appel à AbstractVisitor::visit(ComplexObject/* const */ &) */
       v.visit(*this);
    }
    Le tout pourrait parfaitement être utilisé 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
    struct Functor
    {
        void operator()(Base * ptr)
        {
             ConcreteVisitor v;
             ptr->accept(v);
        }
    }
    int main()
    {
         std::vector<Base*> tab;
         /* remplissage du tableau */
         /* requière l'inclusion du fichier <algorithm>...
          * invoque l'opérateur () issu de Functor pour chaque élément 
          * contenu dans le tableau
          */
         std::for_each(tab.begin(),tab.end(),Functor());
    }
    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

  4. #4
    Membre averti Avatar de MacPro
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    367
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 367
    Points : 344
    Points
    344
    Par défaut
    salut

    moi je ne m'embêterais pas, puisque les classes filles capables de traiter un fichier complexe ou non sont différentes alors il te faut un moyen de savoir qu'elles sont différentes, cela peut passer par un flag par exemple.
    Si tu n'as que deux cas (minimaliste et complexe) alors tu pourrais aussi avoir dans la classe mère une fonction virtuelle comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    virtual bool isMinimalist(void) { return true; }
    ta classe fille dite 'complexe' redéfinirait comme cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    virtual bool isMinimalist(void) { return false; }
    Ensuite, lorsque tu cherches à afficher le contenu d'une liste en ayant un pointeur sur le type parent (ici la classe mère) dans le vector par exemple, tu peux au moment de la sélection appeler isMinimalist();

    Par exemple (pseudo code) si tu as :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    QList<mother*> list;
     
    // ... remplissage de la liste
     
    sur sélection d'une liste tu peux ensuite griser ou non ton bouton :
     
    mother* item = list.at(i);
    filterButton->setEnabled(!item->isMinimalist());
    Lorsque vous avez trouvé solution à votre problème, n'oubliez pas de cliquer en bas de la page
    Besoin d'un photographe de mariage : http://www.triangle-photo.fr

  5. #5
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Pour bénéficier ici de l'héritage, l'idée est que le comportement lié à chaque objet soit spécifique, mais avec une interface unique. Le tout est de trouver point commun et spécificités.

    Qu'est-ce qui est commun ? Certaines données. Qu'est-ce qui est spécifique : Une possibilité de traitement supplémentaire.

    Vu comme ça, on se retrouve bloqué... Car on parle de nature plus que de comportement.

    Mais si on regarde le problème d'un autre angle :

    Qu'est-ce qui est commun ? Chaque objet doit pouvoir créer une représentation dans l'IHM. Qu'est-ce qui est spécifique : Chaque représentation est différente.

    Maintenant, regardons ces représentations. Qu'ont-elles en commun ? Elles doivent répondre à des impératifs techniques liés à la bibliothèque d'IHM (désolé, je n'ai pas fait de Qt depuis trop longtemps, je ne peux pas être plus précis. Ca signifie probablement un truc comme : dériver d'un QControl). Elles seront aussi assez semblables (mais ça, c'est plus une commonalité d'implémentation qu'un point impactant l'interface). Qu'ont-elles de spécifique ? Elles n'ont pas le même contenu.

    Donc, on pourrait se diriger vers un truc comme :
    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
     
    class Base
    {
      virtual Representation* CreateRepresentation() = 0;
      // Peut-être d'autres choses ?
    };
     
    class Simple : Base 
    {
      virtual Representation* CreateRepresentation()
      { return new RepresentationSimple(this); }
    };
    class Complexe : Base {...};
     
    class Representation
    {
      virtual void CreateSubControls();
    };
     
    class RepresentationSimple
    {
      RepresentationSimple(Simple *data);
      virtual void CreateSubControls()
      {
        Representation::CreateSubControls();
        // On ajoute / enlève / modifie ce qui est spécifique à notre représentation
      }
     
    };
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

Discussions similaires

  1. Réponses: 13
    Dernier message: 02/03/2007, 14h43
  2. [Décorateur] [Java] Quel modele de conception choisir au lieu de l'heritage ?
    Par Xiao-An dans le forum Design Patterns
    Réponses: 18
    Dernier message: 17/02/2007, 23h31
  3. [conception GUI] heritage des vues ?
    Par avtonio dans le forum Interfaces Graphiques en Java
    Réponses: 7
    Dernier message: 05/09/2006, 14h54
  4. [heritage][conception]héritage multiple en java!
    Par soulhouf dans le forum Langage
    Réponses: 9
    Dernier message: 25/08/2005, 20h03
  5. Conception avec héritage
    Par Mr N. dans le forum Diagrammes de Classes
    Réponses: 31
    Dernier message: 04/07/2005, 18h59

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