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 :

Conseil de conception


Sujet :

C++

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut Conseil de conception
    Bonjour à vous,
    je dois écrire 2 classes A et B qui ne doivent avoir qu'une seule instance.
    A doit pouvoir accéder à tous les membres de B, sans en dériver. (A contient un B ; A ne dérive pas de B)
    B ne contient que des champs, elle n'a pas vraiment de fonctionnalités (c'est plutôt une classe de ressurces)

    Donc pour le moment, j'ai fait :

    A : classe singleton
    contient un B*

    B : classe singleton
    Tous les membres de B en public pour que A puisse y accèder.
    En effet si je déclare A amie de B, je risque de perturber mon implémentation singleton de B à partir de A, car A risquerait de pouvoir accéder au constructeur privée de B.

    Mais je trouve ça un peu pourri ...

    Comment vaut-il mieux procéder ?

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Est-ce que B doit être utilisée par autre chose que A ?

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    non.
    Tu pensais à intégrer directement B dans A, non ? (c'est à dire à faire disparaître B?)

  4. #4
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    je dis peut être une bétise, mais on pourrait donner une variable statique à B:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    //B.hpp
    class B
    {
      static bool wasInit;
      ...
    };
    dans le cpp de la classe B on fait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //B.cpp
    static bool B::wasInit = 0;
     
    B::B()
    {
      //si déjà une instance
      assert (wasInit != 1)
      wasInit = 1;
     
      ...
    }
    Comme ça on ne pourrait créer qu'une seule instance de B.

  5. #5
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Tu pensais à intégrer directement B dans A, non ? (c'est à dire à faire disparaître B?)
    Oui, éventuellement. Mais bon si les rôles sont bien séparés, garder deux classes distinctes restera plus clair. Dans ce cas, personnellement je ferais de B une classe privée imbriquée dans A, et non singleton.

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    Coyotte : le problème n'est pas dans la réalisation du singleton mais plutôt dans les rôles et des 2 classes.
    Sinon ta conception assure que oui il n'y aura qu'une seule instance de B, mais elle n'interdit pas d'appeler son constructeur pour essayer d'en créer de nouvelles. C'est tout l'interêt du singleton qui ne déclare qu'une seule instance, statique.

    Laurent :
    Mais bon si les rôles sont bien séparés, garder deux classes distinctes restera plus clair.
    Oui, c'est exact.
    je ferais de B une classe privée imbriquée dans A
    OK, je vais voir ce que ça donne.

    Valefor :
    C'est pas indispensable d'avoir un singleton de B je pense.
    Ben pour mon architecture, on en doit avoir qu'un seul B.
    Aprés que B soit singleton, ou classe privée imbriquée dans A comme le propose Laurent, ou autre .. là est la question.


    MERCI

  7. #7
    Membre habitué
    Inscrit en
    Mai 2007
    Messages
    157
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mai 2007
    Messages : 157
    Points : 151
    Points
    151
    Par défaut
    Citation Envoyé par coyotte507
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    //B.hpp
    class B
    {
      static bool wasInit;
      ...
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    //B.cpp
    static bool B::wasInit = 0;
    B::B()
    {
      //si déjà une instance
      assert (wasInit != 1)
      wasInit = 1;
      ...
    }
    Comme ça on ne pourrait créer qu'une seule instance de B.
    Ce genre de declaration fait, je pense, qu'appeler une methode qui ne possedera pas l'accesseur a B te permettant de savoir reelement si "wasInit" est different de 1.

    Une technique a adopter dans ces cas la peut etre de faire un manager qui fait les appels a tes constructeurs de A et de B et qui possede en plus la partie logique de gestion
    Classe C qui ne derive ni de A ni de B mais qui est capable de stocker toutes les instances (pointeurs) de A et de B et donc de faire des "stats" sur l'utilsation de tes classes. Le manager revient a une vulgaire BDD dans laquelle tu stockes l'ensemble des infos dont tu as besoin.

  8. #8
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Points : 833
    Points
    833
    Par défaut
    Citation Envoyé par olive_le_malin
    B ne contient que des champs, elle n'a pas vraiment de fonctionnalités (c'est plutôt une classe de ressurces)
    Juste pour info.
    Lorsqu'une classe ne contient que des champs. Une bonne manière est, je pense, d'en faire un struct. Je sais que ça ne change pas grand chose niveau implémentation mais disons que c'est plutôt une question d'ordre philosophique.
    Linux > *

  9. #9
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Points : 833
    Points
    833
    Par défaut
    Sinon pour répondre plus à ta question. Imbriqué B dans A comme le suggérait Laurent me semble une bonne idée
    Linux > *

  10. #10
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    Bonjour,
    en effet ça m'a l'air pas mal, je vais faire comme ça (et en struct éventuellement ... )

    PAr contre : comme je l'ai vu dans d'autres posts, le compilo ne va-t-il pas interpreter tout ça comme un simple friend ?

  11. #11
    Membre habitué
    Inscrit en
    Mai 2007
    Messages
    157
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mai 2007
    Messages : 157
    Points : 151
    Points
    151
    Par défaut
    Juste pour donner mon avis...

    Lorsque l'on fait de la prog c++, il faut eviter les struct et preferer la declaration dans une classe au pire en public, mais l'interet est de permettre une evolutivite du systeme un peu plus tard sans avoir a refaire la structure. Je parle en connaissance de cause ...

    Dans mon projet actuel, trois struct ont ete implementee, d'aspect basique, mais lorsqu'il a fallu ajouter des verifications sur les valeurs stockées dans la struct.... la c'etait plus galere. Mieux vaut un bon fichier header avec la description de ta classe, sans cpp dans un premier temps si il n'y a pas de methodes, mais au moins, un fichier par classe, une possibilité d'évolution simplifiée

  12. #12
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    PAr contre : comme je l'ai vu dans d'autres posts, le compilo ne va-t-il pas interpreter tout ça comme un simple friend ?
    Comment ça ?
    Le seul effet que cela va avoir est que seule la classe A aura connaissance de B. Les amis de A aussi, mais si ça pose problème ça peut s'arranger facilement.

  13. #13
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    Par contre, comment est assurée ma contrainte d'unicité de B ?

  14. #14
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Par le fait qu'il n'y a qu'un seul A, et que seul un A peut créer un B.

  15. #15
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    Oui je suis d'accord, mais qu'est ce qui empêche une fonction A::fct() de créer d'autres B ?

  16. #16
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Rien. Mais dans ce cas on peut pousser un peu le raisonnement et dire "qu'est-ce qui empêche A de créer un autre A ?", par exemple. Pour moi A et B sont la même entité, il n'y a deux classes que parce qu'il y a deux rôles. Mais la garantie que A est unique devrait suffire à garantir que B l'est aussi, non ?

    Bon, au pire si tu n'as vraiment pas confiance en celui qui maintient la classe A et que tu veux garantir fortement l'unicité de B, rien ne t'empêche d'en faire aussi un singleton. Ou mieux, vu que B ne contient que des données : en faire un monostate (que des membres statiques).

  17. #17
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Points : 833
    Points
    833
    Par défaut
    Citation Envoyé par olive_le_malin
    Oui je suis d'accord, mais qu'est ce qui empêche une fonction A::fct() de créer d'autres B ?
    Tu peux sans doute créer un mécanisme similaire au DP singleton mais interne à ta classe A. Genre tu crée le B lors de la création de A et renvoie cette instance lorsqu'on te demande un nouveau B.
    Mais est ce bien utile... si tu as le contrôle de tes classes et que B est interne à A ?
    Linux > *

  18. #18
    Membre habitué
    Inscrit en
    Mai 2007
    Messages
    157
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mai 2007
    Messages : 157
    Points : 151
    Points
    151
    Par défaut
    C'est pour cela que je te parlais d'un manager.....

  19. #19
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    Merci à vous tous pour vos réponses.
    C'est vrai que "j'exagère un peu" avec cette unicité, mais c'était aussi pour voir les différentes possibilités offertes sur B : singleton, monostate (avec lequel j'avais déjà hésité), ...

    Bon, au pire si tu n'as vraiment pas confiance en celui qui maintient la classe A
    C'est moi !

    Mais est ce bien utile... si tu as le contrôle de tes classes et que B est interne à A ?
    Ouais, ça rejoint ce que dit Laurent.

  20. #20
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    Donc au final, j'ai fait comme ça :
    A singleton
    A contient un B

    B est une classe imbriquée privée dans A
    B est sans notion de singleton, avec constructeur de copie et d'affectation privés (car l'instance de B ne doit pas être "manipulée" ...)

    Je pense effectivement que faire du singleton pour du singleton n'est pas une bonne idée. Là, je sais ce que je dois faire ou pas, et j'ai pris les précautions pour le faire.


    PS : j'ai ajouté 2 petites fonctions Setter, et ça me fait bizare de les déclarer comme ça : A::B::set()

    Merci à vous pour tous vos éclairages.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [POO] Conseils pour conception logicielle en php
    Par mithrendil dans le forum Langage
    Réponses: 14
    Dernier message: 07/02/2008, 17h19
  2. Conseils en Conception / Architecture
    Par olive_le_malin dans le forum C++
    Réponses: 4
    Dernier message: 03/02/2007, 02h18
  3. conseil pour conception de base
    Par karidrou dans le forum Modélisation
    Réponses: 1
    Dernier message: 16/01/2007, 18h11
  4. Conseil de conception
    Par PadawanDuDelphi dans le forum Delphi
    Réponses: 6
    Dernier message: 30/10/2006, 18h07
  5. Conseil sur conception : Référencer les applications
    Par alladdinbh dans le forum Modélisation
    Réponses: 3
    Dernier message: 25/09/2006, 17h19

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