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 :

Question de design et de généricité


Sujet :

Langage C++

  1. #1
    Futur Membre du Club Avatar de lilivve
    Homme Profil pro
    Creative coding
    Inscrit en
    Mars 2018
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Creative coding
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mars 2018
    Messages : 7
    Points : 6
    Points
    6
    Par défaut Question de design et de généricité
    Bonjour,

    Bon, désolé pour le titre, je n'ai pas trouvé comme résumer moins vaguement ce qui m'amène !

    Je cherche une bonne façon de programmer ceci :

    - J'ai une collection d'objets instances d'une même classe A
    - Je veux donner à l'utilisateur du programme une interface graphique (GUI) qui lui permette de modifier les attributs d'un de ces objets au choix
    - Il ne doit y avoir qu'une GUI affichée en même temps

    Je vois plusieurs possibilités :

    Approche 1 - La classe A implémente la GUI, qu'on peut activer ou désactiver
    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
    class A {
    public:
        void setGuiActive( bool active );
        void displayGui();                // Affiche le GUI seulement s'il est activé
        void foo();
    };
     
    vector< A > objects( 10 ); // vector pour l'exemple, mais d'autre conteneurs pourraient être utilisés
    objects.back().setGuiActive( true );
     
    void mainLoop(){
        for( A & a : objects ){
            a.foo();
            a.displayGui();
        }
    }
    Je n'ai pas rendu visible dans cet extrait de code le fait que la classe A a des variables membres, que la GUI permet de modifier les valeurs de certaines de ces variables, et que le résultat de foo() est fonction de ces valeurs.

    Deux inconvénients avec cette approche :
    - Il faut implémenter un mécanisme qui assure qu'une seule GUI est active
    - Si la GUI utilise de nombreuses variables membre, la classe A est alourdie pour rien

    Approche 2 - La classe A implémente la GUI, et une variable référence l'objet pour lequel on veut afficher la GUI
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class A {
    public:
        void displayGui();
        void foo();
    };
     
    vector< A > objects( 10 );
    A * selected = &objects.back();
     
    void mainLoop(){
        for( A & a : objects ) a.foo();
        if( selected ) selected->displayGui();
    }
    Ceci résout le premier inconvénient de l'approche 1, mais pas le 2eme:
    - Si la GUI utilise de nombreuses variables membre, la classe A est alourdie pour rien

    Approche 3 - La GUI est implémentée dans une autre classe
    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
    class A {
    public:
        void foo();
    };
     
    class Gui {
    public:
        void setTarget( A * target);
        void display(); // N'affiche rien si target n'est pas définie
    private:
        A * target = nullptr;
    };
     
    vector< A > objects( 10 );
    Gui gui;
    gui.setTarget( &objects.back() );
     
    void mainLoop(){
        for( A & a : objects ) a.foo();
        gui.display();
    }
    Ceci résout les 2 inconvénients de l'approche 1, mais en introduisant l'inconvénient que Gui référence un object A

    Cette 3e approche me semble préférable car elle ne surcharge pas la classe A, et je pars donc sur cette option. Mais peut-être aurez-vous déjà des suggestions quand à ce choix, ou une autre approche à proposer ?

    Etant parti sur cette 3e approche, je cherche a bien gérer le fait que Gui référence un objet A.

    Dans l'exemple que j'ai donné, c'est à l'utilisateur de Gui de faire attention à l'utilisation de pointeur invalide:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    vector< A > objects( 10 );
    Gui gui;
    gui.setTarget( &objects.back() );
    objects.clear();
    gui.display(); // Aïe ! Le target de gui n'est plus valide
    Il serait possible d'utiliser un weak_ptr pour prévenir ce problème:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Gui {
    public:
        void setTarget( weak_ptr<A> target );
        void display(); // N'affiche rien si target.lock() n'est plus valide
    private:
        weak_ptr<A> target;
    };
     
    vector< share_ptr<A> > objects;
    for( int i = 0; i < 10; ++i ) objects.push_back( make_shared<A>() );
    Gui gui;
    gui.setTarget( &objects.back() );
    objects.clear();
    gui.display(); // Ouf, l'utilisation et le test du weak_ptr prévient le bug
    Je parle d'utilisateur de la classe Gui car c'est un code que je vais partager, et je voudrais donc concevoir un combo A + Gui qui soit assez générique pour d'adapter aux différents besoins des utilisateurs de ses classes, que ce soit d'autres personnes ou moi-même dans 2 ans.

    Comme cela me gène d'imposer à l'utilisateur de Gui l'usage de shared_ptr pour créer ses objects A, j'en suis venu à envisager la création d'une classe Gui qui puisse au choix utiliser un pointeur nu ou un weak_ptr. Pour faire cela j'ai posé cette question sur le forum. Et c'est parce-que koala01 y écrit que mon design lui semble douteux que j'en viens à vous demander vos avis dans ce présent sujet.

    Que pensez-vous de mon choix de l'approche n°3 ?
    Que pensez-vous de vouloir offrir à l'utilisateur le choix de sa stratégie de construction et destruction des objets A ?

    Merci !

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 112
    Points : 165
    Points
    165
    Par défaut
    Salut, tu peux t'inspirer de l'architecture Modèle-Vue, qui est un concept plutôt éprouvé et utilisé par de nombreux framworks.
    https://fr.wikipedia.org/wiki/Mod%C3...ontr%C3%B4leur
    Donc à priori, plutôt l'approche 3.

  3. #3
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Bonjour

    https://en.wikipedia.org/wiki/Single...lity_principle --> ta classe A gère des données, elle ne doit pas gérer la GUI, sinon elle n'a plus une seule responsabilité.

    En fait, quand tu décris ton problème, tu te donnes toi-même la solution :

    - J'ai une collection d'objets instances d'une même classe A
    - Je veux donner à l'utilisateur du programme une interface graphique (GUI) qui lui permette de modifier les attributs d'un de ces objets au choix
    - Il ne doit y avoir qu'une GUI affichée en même temps
    Tu parles bien de 2 classes (A et GUI) et tu parles d'une contrainte sur l'une des 2 (la GUI doit être unique). Cette unicité se gère dans la GUI.

    Quant à ton problème de référencer des objets invalides, il y a pour moi une erreur de flow d'utilisation de ton programme. Tu as ta collection, tu te dis "tiens je vais la modifier", mais tu détruis ta collection avant d'avoir fini les modifications. Ce n'est pas logique...

Discussions similaires

  1. [JMS] Question de design
    Par El Saigneur dans le forum Java EE
    Réponses: 2
    Dernier message: 30/09/2008, 17h58
  2. Question de design
    Par hpavavar dans le forum Hibernate
    Réponses: 0
    Dernier message: 06/08/2008, 11h46
  3. Question de design
    Par Dohmaker dans le forum ASP.NET
    Réponses: 3
    Dernier message: 24/09/2007, 19h29
  4. Question de design?
    Par Jayceblaster dans le forum Delphi
    Réponses: 9
    Dernier message: 06/06/2006, 19h38
  5. [Struts] question de design
    Par mlequim dans le forum Struts 1
    Réponses: 4
    Dernier message: 26/10/2005, 12h27

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