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 :

Conception : strategie, barriere, facade et autres patterns


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Octobre 2009
    Messages
    118
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 118
    Par défaut Conception : strategie, barriere, facade et autres patterns
    Bonjour,

    Je travaille actuellement sur un projet dans lequel je souhaite faire le point sur de nombreux points de conception.
    Dans ce projet, j'ai un grand nombre de classes qui ont en commun d'avoir un identifiant numérique unique. L'identifiant n'est pas toujours du même type.
    Au départ, cet identifiant représente la clef de la table SQL que la classe représente. Je reviendrais plus tard sur l'aspect base de données.

    Pour représenter ce caractère commun mais variable en type, j'ai crée une classe template :

    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
     
    #ifndef __TableTrait_h__
    #define __TableTrait_h__
     
    #include <QtCore/QString>
    #include <QtCore/QStringList>
    #include <QtCore/QList>
    #include <QtCore/QMap>
     
    template<typename KeyType>
    class QTableTrait
    {
    // Construction Destruction
    public:
    	QTableTrait( void );
    	~QTableTrait( void );
     
    // Types membres publics
    public:
    	typedef KeyType							QKeyType;
    	typedef QList<ClassName*>					QRowList;
    	typedef QMap<QKeyType,ClassName*>				QRowMap;
     
    // Fonctions membres publiques
    public:
    	//! Retourne la valeur de la clef dans la table pur cette instance
    	QKeyType	key						( void ) const;
     
    	//! Modifie la valeur de la clef dans la table pur cette instance
    	void		setKey						( const QKeyType &p_oKey );
     
     
    protected:
    	//! Valeur de la clef dans la table pour cette instance
    	QKeyType							m_oKey;
    };
     
    #include "TableTrait.cpp"
    J'utilise Qt4/VS2005 pour ce projet.
    Jusqu'ici pas de problème. L'utilisation se fait facilement.

    Là ou cela se corse pour moi, c'est que les classes qui utilisent cette template ont besoin d'initialiser leurs variables membres lors de l'instanciation. (elles sont initialisées une fois seulement lors de l'instanciation)

    Chaque classe a bien sûr des membres différents et certaines sont composées d'autres classes qui héritent aussi de QTableTrait.

    Ce que je veux faire c'est définir une structure de classes qui permette de
    - rendre commun l'interface de lecture des données pour toutes les classes (sachant que pour lire une base de données il faut quelques paramètres)
    - séparer la lecture des données de la classe de "stockage"
    - permettre facilement de changer de mode de lecture des données (passer d'une lecture SQL à une lecture d'un fichier XML par exemple)
    - prenne en compte qu'une classe peut etre composée d'autres classes du type QTableTrait et donc que ces sous classes doivent aussi etre initialisées

    Pour cela j'ai pensé utiliser le pattern "stratégie". Mais je ne vois pas comment le mettre en oeuvre dans mon cas....

    J'ai actuellement une architecture qui fonctionne mais qui n'est pas du tout adaptée a ce que je cherche à faire. Elle est basée sur une version modifiée de la template ci dessus, mais le code est un peu long. Si vous voulez y voir plus clair je peux le poster ici.

    Merci d'avance !

  2. #2
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Décembre 2011
    Messages : 54
    Par défaut
    Bonjour,

    Pour mieux comprendre ta problématique, quelques questions:

    Là ou cela se corse pour moi, c'est que les classes qui utilisent cette template ont besoin d'initialiser leurs variables membres lors de l'instanciation. (elles sont initialisées une fois seulement lors de l'instanciation)
    Pourquoi cela est-il un problèlme dans ton cas? Quelles difficultés as-tu rencontré?

    Pour cela j'ai pensé utiliser le pattern "stratégie". Mais je ne vois pas comment le mettre en oeuvre dans mon cas....
    Je ne connaissais pas ce pattern, mais en prenant le premier lien sur google (article wikipedia), c'est assez clair. Quel problème se pose dans ton cas?

    Je travaille sur un project où je vais également mettre en place une abstraction de la couche persistance, et je me suis tourné vers les concepts de DataAccessObject et DataTransferObject. Ceux-ci sont assez simples, voici une page explicative qui traite de ces deux concepts étroitement liés.

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Octobre 2009
    Messages
    118
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 118
    Par défaut
    Citation Envoyé par vravier Voir le message
    Pourquoi cela est-il un problèlme dans ton cas? Quelles difficultés as-tu rencontré?
    He bien si j'ai bien compris, je dois faire une classe abstraite à la base de ma strategie, disons QAbstractParamReader
    puis pour lire les paramètre je peux spécialiser cette classe en SQLParamReader ou XmlParamReader.
    Jusqu'ici c'est bon
    Mais ce qui est mon sympa c'est que j'ai plein de classes qui doivent utiliser cette stratégie.
    Par exemple J'ai la classe QTrieur et QSortie. Alors dans ce cas il me faut deux implémentations de la lecture dans la base. Une pour le trieur, une autre pour les sorties. Si j'ai deux stratégies, il me faut alors quatre implémentations. C'est c'est un peu lourd mais c'est gérable.
    Disons que je fasse cela : j'ai alors TrieurSQLParamReader et SortieSQLParamReader

    Ce que je ne sais pas en revanche, c'est comment faire pour m'assurer que je passe la bonne stratégie à la bonne classe ??? Ou encore comment empêcher (si possible à la compilation) que l'on utilise SortieSQLParamReader sur QTrieur ???


    Citation Envoyé par vravier Voir le message
    Je travaille sur un project où je vais également mettre en place une abstraction de la couche persistance, et je me suis tourné vers les concepts de DataAccessObject et DataTransferObject. Ceux-ci sont assez simples, voici une page explicative qui traite de ces deux concepts étroitement liés.
    En effet cela parait se rapprocher de ce que je cherche a faire, je vais regarder cela aussi en parallèle...
    Merci

  4. #4
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Décembre 2011
    Messages : 54
    Par défaut
    En effet, si tu as N objets métier, et M types de source différentes, tu auras NxM implémentations de classe gérant la persistance. Je n'ai pas vu de façon de faire qui évite ça. A un moment donné, il faut bien que le code soit spécifique à quelque chose. Les couches d'astraction sont là pour masquer tout ça, mais quelqu'un doit bien se taper le sale boulot

    Pour ce qui est de l'utilisation de la bonne implémentation de la classe gérant la persistance, en fait ton objet interrogera toujours une classe mère. Par exemple, QTrieur pointe sur un QTrieurAbstractParamReader, qui cache derrière un QTrieurSQLParamReader, ou un QTrieurXMLParamReader.

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Octobre 2009
    Messages
    118
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 118
    Par défaut
    Bon si j'ai bien compris, j'obtiens une truc du genre de ça :



    Vous en pensez quoi ?

  6. #6
    Invité
    Invité(e)
    Par défaut
    salut,

    je pense qu'on peut considérer, que Qtrieur et Qsortie contiennent un reader.
    Donc avoir qqch comme
    Leur parent contient un Reader*

    Reader peut etre Xml ou SQL.
    Or, tu veux t'assurer que si tu utilises un Qtrieur tu utilises bien un reader de type Qtrieur.

    Bon je sais pas trop ce que font Qtrieur et Qsortie mais supposons qu'ils ont un parent Qparent...
    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
     
    #include <iostream>
    template<class T>
    class Reader{
    protected:
     Reader(){}
    };
     
    template<class T>
    class Parent{
      public:
      Reader<T>* reader;
    };
     
    class QTrieur:public Parent<QTrieur>{
     
    };
    class QSortie:public Parent<QSortie>{
     
    };
    class QTrieurReaderXml:public Reader<QTrieur>{
     
    };
    class QTrieurReaderSql:public Reader<QTrieur>{
     
    };
    class QSortieReaderXml:public Reader<QSortie>{
     
    };
    int main(int argc, char** argv)
    {
      QTrieur a;
      QTrieurReaderXml txml;
      QTrieurReaderSql tsql;
      QSortieReaderXml sxml;
      a.reader=&txml;
      a.reader=&sxml;//fails because sxml is of type Sortie and not Trieur
      return 0;
    }
    Au final tu as "effacé" la factory en fixant le type du reader (QTrieur ou QSortie) à la compilation.

    je passe outre les membres publics constructeurs parent et virtual destructors...

Discussions similaires

  1. Problème de conception : factory ou autre pattern?
    Par floctc dans le forum Langage
    Réponses: 2
    Dernier message: 13/04/2010, 16h38
  2. [Regexp] Remplacer un pattern dans un autre pattern ?
    Par titoumimi dans le forum Langage
    Réponses: 4
    Dernier message: 31/10/2006, 09h36
  3. [Conception] SELECT dépendant d'un autre (avec BDD)
    Par banzzai dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 07/08/2006, 17h57
  4. [Conception][Strategie] Combien de classes ?
    Par oceane751 dans le forum Général Java
    Réponses: 17
    Dernier message: 07/07/2005, 15h06
  5. Réponses: 2
    Dernier message: 07/10/2004, 16h31

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