Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 5 sur 5
  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    août 2006
    Messages
    605
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : août 2006
    Messages : 605
    Points : 419
    Points
    419

    Par défaut AbstractFactory pour des classes template

    Bonjour,

    Je me trouve dans une situation un peu tordue, que j'essaye de schématiser ci-dessous. En gros, des objets de classes templatisées doivent être créés par une abstract factory... du coup, il y aurait besoin d'écrire quelque chose comme :
    Code :
    FACTORY<AbstractComportement,line>::Instance()->GetObject(comp);
    Jusque-là, la factory que nous utilisions n'avait qu'un paramètre template (AbstractComportement, mettons) et la déclaration des comportements à la factory se faisait depuis leur fichier d'implémentation via une macro :
    Code :
    DECLARE_COMPORTEMENT(Comportement,"mot_clef");
    Mais est-ce qu'une telle stratégie demeure possible si la factory dépend d'un deuxième paramètre template ? Est-ce faisable de lister des choses comme ça :
    Code :
    1
    2
    DECLARE_COMPORTEMENT(Comportement, line1,"mot_clef");
    DECLARE_COMPORTEMENT(Comportement, line2,"mot_clef");
    dans les fichiers d'implémentation des classes comportement ?

    Ci-dessous, la situationsous forme un peu plus codée... Toute aide serait la bienvenue !!

    Merci tout plein :-)

    Marc

    Code :
    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
    class base
    {
        public:
        virtual void Fonction1() = 0;
    }
     
    class AbstractComportement
    {
        public:
        virtual void Comportement() = 0;
    }
     
    template<typename line> class Comportement1 : public AbstractComportement
    {
        public:
        virtual void Comportement()
        {
            //blabla
        }
    }
     
    class line1{
        //blabla
    }
     
    class line2{
        //blabla
    }
     
    template<typename line>class derive : public base
    {
        public:
        virtual void Fonction1()
        {
            //blabla
        }
     
        derive(string comp)
        {
         pcomportement = FACTORY<AbstractComportement,line>::Instance()->GetObject(comp); //est-ce viable ?
        }
     
        private:
        AbstractComportement* pcomportement;
     
    }
    Faut-il faire une déclaration de ce type :
    Code :
    1
    2
    3
    4
    5
    6
    #define DECLARE_COMPORTEMENT(CLASS_NAME,KEYWORD)                    \
      namespace {                                                           \
        AbstractComportement* creator(){ return new (CLASS_NAME);}      \
        const string kwords(KEYWORD);                                       \
        const bool registered = Factory<AbstractComportement,line>::Instance().Register(kwords,creator); \
      }
    Est-ce que la chose se passe bien en déclarant via la macro depuis le fichier de comportement pour chaque line ??

  2. #2
    Expert Confirmé Sénior


    Homme Profil pro Denis
    Étudiant
    Inscrit en
    décembre 2011
    Messages
    5 003
    Détails du profil
    Informations personnelles :
    Nom : Homme Denis
    Âge : 21
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2011
    Messages : 5 003
    Points : 14 900
    Points
    14 900

    Par défaut

    Bonjour,

    Je ne comprend pas trop l'intérêt de la macro. Est-ce que des fonctions/classes templates ne suffisent pas?

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    août 2006
    Messages
    605
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : août 2006
    Messages : 605
    Points : 419
    Points
    419

    Par défaut

    Bonjour,

    Merci pour ta question. Je ne saurais pas l'écrire avec des template, je dois dire... Mais mon inquiétude est surtout la faisabilité d'un tel schéma, et si c'est faaisable, comment rendre les choses maintenables, par exempleà la création d'un nouveau type line, comment déclarer les nouvelles factory, etc... ?

    Marc

  4. #4
    Expert Confirmé Sénior


    Homme Profil pro Denis
    Étudiant
    Inscrit en
    décembre 2011
    Messages
    5 003
    Détails du profil
    Informations personnelles :
    Nom : Homme Denis
    Âge : 21
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2011
    Messages : 5 003
    Points : 14 900
    Points
    14 900

    Par défaut

    Bonjour,

    J'ai un peu du mal à comprendre ce que tu veux faire.

    Si je comprend bien, tu as une factory donc le comportement est défini par un paramètre template "Comportement" (en gros un design pattern stratégie) et avec comme second paramètre template line dont on ne sait pas trop ce qu'il fait (mais cela ne semble pas très important).

    Ensuite, tu as une macro DECLARE_COMPORTEMENT dont je ne comprend vraiment pas à quoi elle sert : tu peux avoir deux fonctions de même signature dans un même namespace, je serais d'ailleurs étonné si ça compile correctement.

    Pour faire l'équivalent de ta macro :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    template<typename Type, std::string mot>
    class ??
    {
         AbstractComportement* creator(){ return new Type;}
         const string kwords(mot);
         const bool registered = Factory<AbstractComportement,line>::Instance().Register(kwords,creator);
     
    };
    Sinon j'ai plus l'impression que ta macro sert de Factory et ta Factory sert de pool.

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    août 2006
    Messages
    605
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : août 2006
    Messages : 605
    Points : 419
    Points
    419

    Par défaut

    Bonjour,

    Merci pour ta réponse, et désole pour l'extrême lenteur des miennes : horaires un peu variables ces temps-ci... Bref. Ici, la macro sert à s'enregistrer auprès de l'abstract factory, qui est construite sur le modèle d'Alexandrescu dans modern C++ design.
    Un peu plus de contexte, peut-être...
    Il s'agit d'un code de modélisation de lignes, qui peuvent être de différents types. Les types sont définis pour des zones spatiales données (appelées graph, sans relation avec les autres types de graphes...), et sont des templates de ligne.
    Le type de graph est assigné à la lecture du fichier de mise en donnée, c'est en gros un conteneur un peu savant. Et le procédé est assez atroce :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
              if ((*gr)->GetLineType() == "line")
                _graphs[(*gr)->GetTag()]=new CommandGraph<Line>(*this,
                    (*gr)->GetTag(),
                    graphbox,
                    graphmin,
                    graphmax,
                    egrid);
              else if ((*gr)->GetLineType() == "faultedline")
                _graphs[(*gr)->GetTag()]=new CommandGraph<FaultedLine>(*this,
                    (*gr)->GetTag(),
                    graphbox,
                    graphmin,
                    graphmax,
                    egrid);
              else if ((*gr)->GetLineType() == "LineHighPeierls")
                _graphs[(*gr)->GetTag()]=new CommandGraph<LineHighPeierls>(*this,
                    (*gr)->GetTag(),
                    graphbox,
                    graphmin,
                    graphmax,
                    egrid);
    Tout cela se passe dans un conteneur de niveau supérieur, qui peut stocker des graphs de types différents via leur interface (appelée CommandGraph).
    À présent, nous avons besoin de définir des comportements différents suivant de nouveaux mot-clefs pour les algorithmes de résolution, qui vont devoir aussi être dépendants du type de Line et d'un mot clef dans la mise en donnée, du coup, il y aurait besoin d'une factory capable de lier les mots-clefs du type ligne et les mots clefs définissant les algorithmes choisis. J'aimerais pouvoir écrire quelque chose comme ça :

    Code :
    Factory<LineType>::GetFactoryInstance().GetAlgorithm("algoKeywords")
    ou peut-être plutôt comme ça :

    Code :
    Factory<Algorithm>::GetFactoryInstance().GetAlgorithm("algoKeywords","lineKeyword")
    Mais je dois avouer que le design d'une telle chose reste assez nébuleux pour moi...

    Merci pour toute suggestion !!

    Marc

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •