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 :

Choix de pattern


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    30
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 30
    Par d�faut Choix de pattern
    Bonjour,

    J'ai un petit probl�me de conception. En effet, j'ai besoin de g�rer un groupe d'objet (de nature diverse avec l'h�ritage) mais je n'y arrive pas.

    Les deux contraintes sont la vitesse et l'automatisation.
    L'ideal c'est que les objets soient automatiquement enregistr�s dans le manager gr�ce � leur constructeur et qu'ils y partent gr�ce � leur destructeur.

    J'ai un truc comme �a :
    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
     
    //Marche pas, seg fault.
    class Foo;
     
    class Manager
    {
    boost::ptr_list< Foo > Foo_List;
     
    public :
     
       void Add_Foo( foo* );//Ajout d'un objet.
     
       void Del_Foo( boost::ptr_list< Foo >::iterator );//Suppr d'un objet.
    };
     
     
     
     
    class Foo
    {
    public :
     
       Foo( Manager * M )
        {M->Add_Foo(this);}
     
      ~Foo()
        {M->Del_Foo( it_Recuperé_Avant );}
    };

    La list est utile car les objets sont d�truits et ajout�s dans un ordre quelconque et r�guli�rement.

    Le code n'est pas utile car je ne cherche pas d'erreur dans le code mais dans la conception.



    Est-ce qu'il y a un pattern pour �a ?
    Sinon, une petite piste svp.

    Cordialement Julien

  2. #2
    Membre exp�riment� Avatar de Nogane
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    241
    D�tails du profil
    Informations personnelles :
    �ge : 45
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 241
    Par d�faut
    Bonjours,
    En effet cette premi�re approche me semble un peu dangereuse. Tout d'abord parque tes objets Foo n'ont pas a connaitre leur manager. Mais surtout parque c'est ta ptr_list qui g�re la dur�e de vie de tes objets. Donc il n'y a aucune raison qu'il soit d�truit par autre chose que la ptr_list.(Alors que la c'est le destructeur de Foo qui appelle sa suppression de la liste, et donc... sa destruction...)

    Dans ce genre de situation j'ai tendance a utiliser des conteneur de shared_ptr plut�t que des ptr_container.
    Pour la cr�ation d'un Foo deux solution, ou tu ajoute ton objet toi m�me dans le manager:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    shared_ptr<Foo> newFoo(new Foo(ID));
    FooManager::Add(newFoo);
    Ou tu donne la possibilit� a ton Manager de cr�er l'objet si il ne l'as pas d�j�:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    shared_ptr<Foo> newFoo = FooManager::Get(ID);
    Perso, je suis un adepte de la deuxi�me solution.

    Pour la destruction, tu ne doit surtout pas d�truire toi m�me ton objet. Deux solution:
    Ou tu demande au manager de s'en d�barrasser:
    Ou tu t'arrange pour qu'il le supprime tout seul quand le Foo ne sert plus. Toute la difficult� est de d�terminer si l'objet ne sert plus. La solution la plus simple �tant de se dire que si il n'y as plus de shared_ptr qui pointent dessus, c'est qu'il ne sert plus. Pour ca on peut par exemple faire un conteneur de weak_ptr, plutot que de shared_ptr, est fair un lock() dans la methode Get().

    Je ne sait pas si il y as un pattern pour ca. D'autre personnes auront peut-�tre d'autre suggestion...

  3. #3
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    D�tails du profil
    Informations personnelles :
    �ge : 51
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par d�faut
    Pour ma part, je d�riverais mes classes "Foo" d'une classe de base sachant s'enregistrer dans un manager, enregistrement effectu� via un appel au constructeur anc�tre...

    Ainsi, au moins, tu ne dupliques pas le code d'enregistrement (ce qui est bien), et surtout tu peux modifier cet enregistrement SANS retoucher au code sp�cifique des classes "Foo"... Ni ajouter dedans un quelconque param�tre "Manager", car tout est fait dans la classe de base.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au s�rieux, de toutes fa�ons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum ad�quat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    30
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 30
    Par d�faut
    Merci pour vos r�ponses, �a marche \o/

  5. #5
    Expert �minent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activit� : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par d�faut
    Salut,

    Je serais plut�t d'avis de travailler en r�alit� avec trois classes pour gerer l'existence de tes objets:
    une classe factory, qui dispose d'une liste d'objet clonable et qui connait le manager, qui travaillerait sur un principe 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
    29
    30
    31
    32
    33
    34
    class Manager;
     
    class Factory
    {
         typedef std::map<TypeId, BaseType*> map;
         typedef typename map::const_iterator const_iterator;
         public:
             static BaseType* create(TypeId  id)
             { 
                 /* éventuellement
                 assert(manager_!=0);  
                 */
                 const_iterator it=items_.find(id);
                 if(it !=items_.end())
                 {
                     BaseType* temp= (*it).second->clone();
                     manager_->registerItem(temp);
                     return temp;
                 }
                 return NULL;
     
             }
             /* ne sera utile que si tu envisage d'avoir plusieurs managers
              * différents et lors de l'initialisation de ton application
              */
             static void changeManager(Manager * man)
             {
                 assert(man!=0);
                 manager_=man;
             }
        private:
            static map items_;
            static Manager * manager_;
    };
    une classe "assassin" qui ne connait que le manager et qui fonctionne sous une forme proche de 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
    class Manager;
    class ItemKiller
    {
        public:
            static void killItem(BaseType* b)
            {
                 /* éventuellement
                 assert(manager_!=0);  
                 */
                 manager_->unregisterItem(b);
                 delete b;
            }  
             static void changeManager(Manager * man)
             {
                 assert(man!=0);
                 manager_=man;
             }
        private:
            static Manager * manager_;
    };
    Et, enfin, la classe Manager elle-m�me qui se contente d'enregistrer et de "d�senregistrer" les diff�rents objets au fur et � mesure:
    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
    class Manager
    {
        typedef std::list<BaseType*> list;
        public:
            typedef typename list::iterator iterator;
            typedef typename list::const_iterator const_iterator;
            void registerItem(BaseType* b)
            {
                items_.push_back(b);
            }
            void unregisterItem(BaseType* b)
            {
                const_iterator it= items_.begin();
                while it!=items_.end() && (*it)!=b;
                    ++it;
                if(it!=items_.end())
                    items_.erase(it);
            }
            iterator itemsBegin(){return items_.begin();}
            const_iterator itemsBegin()const{return items_.begin();}
            iterator itemsEnd(){return items_.begin();}
            const_iterator itemsEnd()const{return items_.begin();}
        private:
            list items_;
    };
    Pour comprendre le tout, il "suffit" de savoir que TypeId est le type qui te permet de d�terminer l'objet r�el qu'il te faut et que la classe BaseType et la classe "anc�tre" de toutes tes classes utiles et qui fournit une interface virtuelle "clone()"

    De cette mani�re, lors de l'initialisation de ton application, tu cr�e le manager, la fabrique et l'assassin, et, lors de l'utilisation, tu appelle la fabrique lorsqu'il te faut un objet et l'assassin lorsque tu n'en a plus besoin: Tu es tr�s proche du respect de la loi demeter, et tu respecte scrupuleusement le principe de la responsabilit� unique.

    Au final, tu peux modifier n'importe quelle classe sans que cela n'influe fortement sur les autres (il faut "juste" veiller � rester coh�rent sur les relations Manager <-->Factory et Manager<-->ItemsKiller)
    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

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. Choix de design pattern
    Par velocity dans le forum G�n�ral Java
    R�ponses: 0
    Dernier message: 25/05/2013, 20h26
  2. choix du pattern
    Par oukacha dans le forum Design Patterns
    R�ponses: 2
    Dernier message: 27/04/2012, 20h29
  3. Choix d'impl�mentation du Pattern Singleton
    Par Sehnsucht dans le forum VB.NET
    R�ponses: 1
    Dernier message: 26/07/2010, 09h54
  4. Choix d'un pattern
    Par guiph dans le forum Design Patterns
    R�ponses: 8
    Dernier message: 13/10/2008, 10h06
  5. Choix de design pattern
    Par xspartacusx dans le forum Design Patterns
    R�ponses: 8
    Dernier message: 12/11/2007, 09h22

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