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 :

Pour ou contre les singletons


Sujet :

C++

  1. #1
    Membre habitué
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2005
    Messages
    147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2005
    Messages : 147
    Points : 165
    Points
    165
    Par défaut Pour ou contre les singletons
    Bonjour,

    J'ai récemment parcouru le forum C++ et j'ai vu beaucoup de membres "experts" s'insurger contre l'utilisation des singletons en C++, mais je n'ai pas trouvé pourquoi.

    J'aimerais donc savoir pourquoi les singletons (que j'utilise de temps à autre) doivent être évités ?
    Dans quels cas sont-ils à utiliser et dans quels cas ne le sont-ils pas, et comment les remplacer ?

    J'espère que ma question est posée au bon endroit, et pas trop vague. J'ai fait quelques recherches bien sur mais je n'ai rien trouvé là dessus (peut être que je ne savais pas quoi chercher). Je peux fournir quelques exemples de situations où j'ai utilisé les singletons, mais j'aimerais pour commencer avoir un avis global sur la question.

    Merci d'avance
    Avec les ordinateurs, 99% des bugs proviennent de l'interface chaise-clavier...

    Comment ça 1Km n'est pas égal à 1024m ???

  2. #2
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    La raison est assez simple, un singleton n'est ni plus ni moins qu'une variable globale déguisé. Donc l'analogie est vite faite . Néanmoins dans certains cas ama il est utile de faire ce genre de concession d'autant plus que certaines implémentations sont vraiment excellente. (je pense à celle de loki là).
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  3. #3
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    Je pense que ta question est mal posée,

    Un singleton peu être très une bonne idée dans certains cas et une très mauvaise dans d'autres.

    les singletons existent, il faut simplement savoir quand et comment les utiliser.

    Ta question c'est un peu comme être pour ou contre le tournevis dans une boite à outil. tu pourra enfoncer un clou avec mais ce n'est pas sont boulot à la base.
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  4. #4
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Le singleton est une forme de variable globale; c'est parfois nécessaire mais c'est tellement une source de couplage et d'ennuis qu'il faut en réduire les utilisations aux cas où c'est nécessaire et pas simplement utiles ou même simplement pratique.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  5. #5
    Membre habitué
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2005
    Messages
    147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2005
    Messages : 147
    Points : 165
    Points
    165
    Par défaut
    Merci pour vos réponses,

    Je comprends que le singleton est à utiliser avec précautions, au même titre que les variables globales, et donc je précise ma question, y'a t'il des cas typiques où leur utilisation est bienvenue, où on ne peut pas faire autrement, ou tout du moins des cas où faire autrement serait pire que de les utiliser ?

    S'il n'y a pas de cas typiques tant pis, je ne demande pas un troll
    Avec les ordinateurs, 99% des bugs proviennent de l'interface chaise-clavier...

    Comment ça 1Km n'est pas égal à 1024m ???

  6. #6
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    Citation Envoyé par Le Mérovingien Voir le message
    Merci pour vos réponses,

    Je comprends que le singleton est à utiliser avec précautions, au même titre que les variables globales, et donc je précise ma question, y'a t'il des cas typiques où leur utilisation est bienvenue, où on ne peut pas faire autrement, ou tout du moins des cas où faire autrement serait pire que de les utiliser ?

    S'il n'y a pas de cas typiques tant pis, je ne demande pas un troll
    Ce qui est bien avec l'informatique c'est qu'il y'a souvent plusieurs efficaces façon de résoudre un problème. je sais cela ne répond pas a ta question
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  7. #7
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    y'a t'il des cas typiques où leur utilisation est bienvenue
    Le cas typique est amha celui où:

    - on a besoin d'un même composant à plein d'endroits différents du programme, y compris dans des modules séparés.

    - on est absolument certain que ce composant n'a de raison d'être qu'en étant unique quoi qu'il advienne dans l'évolution du programme.

    Cela équivaut à élire les cas où l'utilisation d'une autre technique demanderait trop d'efforts comparés au singleton (dans le sens: "le singleton étant plutôt un anti-pattern, on doit l'envisager uniquement quand les autres techniques ont montré leurs limites").

    Il faut en effet garder à l'esprit qu'un singleton pourra toujours être remplacé par une autre technique. Le tout est de cerner les cas spécifiques où les autres techniques seront trop lourdes à mettre en place comparé au singleton.

    Ceci étant dit, tout dépend du contexte. Un exemple x pourra être pertinent dans un cas de figure tandis qu'il pourra être démonté par une personne tierce en te montrant que pour le même concept mais dans un autre contexte, l'utilisation d'un singleton sera source d'ennuis.

    Bon, j'ai assez tourné autour du pot. Je me lance (affutez vos armes ) pour un exemple qui vaut ce qu'il vaut.

    Un système de pool de ressources utilisées en shadow copy pour économiser de la mémoire:

    J'ai un programme qui utilise beaucoup d'images bitmap (icônes, ...) et surtout beaucoup de fois la même image. Si j'utilise 500 fois l'image de l'icône "point d'interrogation". Au lieu de faire une 'deep copy' de l'icône pour chaque endroit où elle est utilisée, on utilise toujours la même référence à cette unique icône. Tu économises 499 fois la place prise en mémoire par ton icône.
    A utiliser en parallèle d'un système de "copy-on-write" lors de la modification d'une icône sur les 500.

    Dans ce cas là, un système centralisé de gestion des images 'en cache' peut-être intéressant. Ca sent typiquement l'implémentation statique du pool dans ta classe image, ce qui revient peu ou prou au même qu'un Singleton.

    Ce genre de cas peut être décliné dans beaucoup de domaines où une gestion centralisée d'une ressource (qui est utilisée à différents endroits) est bienvenue (pour des raisons d'optimisation notamment). Un pool de Thread, un pool de connexions réseau, la gestion des logs, ...
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  8. #8
    Membre habitué
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2005
    Messages
    147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2005
    Messages : 147
    Points : 165
    Points
    165
    Par défaut
    D'accord, merci pour cette réponse.

    Voila le cas où j'ai utilisé un singleton : j'ai créé un gestionnaire de log, qui me permet d'ajouter des messages de log quand et où j'en ai envie, de façon homogène. Le gestionnaire peut être parametrer pour utiliser un fichier, une sortie standart ou n'importe quel ostream comme destination pour les log, cette propriété étant constante (dans le sens où on la déclare une fois, et elle est active tout le temps, jusqu'à ce qu'on la change). On peut aussi sélectionner d'autres valeurs par défaut, comme le niveau de verbosité ou le niveau d'importance des messages (info, warning, erreur, ...).
    Cette classe est donc un singleton, et je peux l'appelée partout où je veux.

    Est ce que l'utilisation d'un singleton dans ce cas vous parait justifiée ? Et si non que proposez vous ?

    Je peux poster le code de cette classe (avec la doc) si celà peut être utile.

    Merci d'avance
    Avec les ordinateurs, 99% des bugs proviennent de l'interface chaise-clavier...

    Comment ça 1Km n'est pas égal à 1024m ???

  9. #9
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    C'est effectivement un cas typique d'une ressource centralisée qui doit être accessible de beaucoup d'endroits différents.

    A titre d'info, le mécanisme de logs standard de Java utilise d'ailleurs la même approche, avec une fonction statique pour récupérer un objet permettant d'enregistrer des logs. Cf. la classe Logger et sa fonction getLogger. Le Logger de Java propose pas mal de rafinements intéressants à découvrir, et qui pourront peut-être te donner quelques idées
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  10. #10
    Membre habitué
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2005
    Messages
    147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2005
    Messages : 147
    Points : 165
    Points
    165
    Par défaut
    @nouknouk : très intéressant ce lien vers les logger java, et je suis content j'ai retrouvé une partie de ce que j'ai fait, la seule différence c'est que j'utilise la surcharge de l'opérateur <<, c'est tellement pratique, mais, bref, là n'est pas le sujet .

    J'utilise également un singleton pour implémenter un gestionnaire d'utilisateurs, mais là je suis beaucoup moins sur de la pertinence de ce choix.

    J'ai une classe User, qui implémente des utilisateurs non copiables, mais il existe un constructeur avec paramètres obligatoires public (les autres constructeurs et l'operateur =() sont privés).
    J'ai également une classe UserManager qui contient une map d'utilisateurs, avec un identifiant uid associé à chaque utilisateur (j'utilise uid comme clé pour ma map). Ce UserManager propose 3 méthodes principales, addUser() qui ajoute un utilisateur en vérifiant au préalable qu'il n'existe pas déjà (pas le meme nom en gros), delUser qui supprime un utillisateur, et getUser qui retourne une référence sur un utilisateur (et lève une exception si l'utilisateur n'existe pas). J'ai implémenté ce UserManager avec un singleton, mais je me pose des questions : n'y aurait-il pas un moyen de gérer l'ensemble des utilisateurs directement à partir de la classe User, sans utiliser de UserManager, ce qui me permettrait de supprimer le singleton, et de stocker directement un pointeur (shared_ptr ?) quand j'en ai besoin, et de pouvoir créer un utilisateur "unique" sans passer par un Manager ? J'ai cherché un pattern pouvant faire ça, mais je n'ai pas trouvé. J'ai bien sur pensé à inclure une map static dans la classe User, mais je ne sais pas si c'est bien. Qu'en pensez vous ? Y'a t'il une solution propre pour faire celà ?

    Je ne sais pas si j'ai été très clair, donc n'hésitez pas à demander des précisions si besoin.
    Avec les ordinateurs, 99% des bugs proviennent de l'interface chaise-clavier...

    Comment ça 1Km n'est pas égal à 1024m ???

  11. #11
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    J'utilise également un singleton pour implémenter un gestionnaire d'utilisateurs, mais là je suis beaucoup moins sur de la pertinence de ce choix.
    Je serais en effet beaucoup plus réservé - à priori - sur l'utilisation d'un singleton dans ce cas précis.

    En effet, si on reprend les deux conditions du "cas typique", on a:

    - "on a besoin d'un même composant à plein d'endroits différents du programme" => Contrairement à un outil de log qui va être potentiellement utilisé dans presque toutes les classes, la gestion des utilisateurs est en règle générale beaucoup plus ciblée à certaines parties précises de l'application.

    - "on est absolument certain que ce composant n'a de raison d'être qu'en étant unique" => Et si demain tu veux évoluer vers plusieurs pools d'utilisateurs, organiser les utilisateurs par groupes, etc... la changement dans ton implémentation risque d'être alourdi par le choix du singleton.

    Ceci étant dit, comme le précisait jabbounet, il y a dans 99% des cas plusieurs approches différentes pour arriver à ses fins
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  12. #12
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    en tout cas il ne faut surtout pas faire d'écriture concurrentielle dessus dans une appli multithreadé.

    goulet d'étranglement assuré.
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  13. #13
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Le Mérovingien Voir le message
    Je comprends que le singleton est à utiliser avec précautions, au même titre que les variables globales, et donc je précise ma question, y'a t'il des cas typiques où leur utilisation est bienvenue, où on ne peut pas faire autrement, ou tout du moins des cas où faire autrement serait pire que de les utiliser ?
    Je vais te conseiller de partir sur une autre voie: comprend quels sont les problèmes posés par les variables globales, comprends les avantages et les inconvéniants des alternatives, tu seras alors capable de choisir en connaissance de cause. Comme dans toute affaire de conception, le contexte joue beaucoup.

    En passant, on peut toujours s'en passer, au prix d'arguments supplémentaires.

    En passant toujours -- et pour apporter un argument en faveur de leur utilisation, les choix de conceptions c'est souvent des compromis --, un problème potentiel de pas mal d'alternatives, est qu'on finit par avoir des chemins d'accès différents au même objet -- celui qui est candidat à être singleton. Et que comme tous les chemins référencent le même objet, on ne détecte pas qu'on les utilise de manière inconsistante. Ce qui peut être plus problématique pour l'évolution de d'être partit sur un singleton (pour commencer on sous-estime le coût d'utiliser réellement plusieurs objets -- le travail est déjà fait, n'est-ce pas?, on n'a pas utilisé de singleton).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  14. #14
    Membre habitué
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2005
    Messages
    147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2005
    Messages : 147
    Points : 165
    Points
    165
    Par défaut
    @jabbounet : tu parles des Logger Java ou des singletons en général ?

    Merci à tous pour vos réponses, je me suis rappelé hier soir pourquoi j'avais besoin d'un singleton, ou d'une variable globale : mon appli est un serveur qui utilise RPC, et je n'ai pas trouvé comment passer le gestionnaire d'utilisateurs dans les fonctions que le serveur appellent : elles ont un prototype fixe qui ne prévoit pas de champs utilisateurs (void* par exemple). Si quelqu'un à la solution sans variable globale je suis preneur.

    Mais comme ce n'est pas le sujet de ce post, je vais le mettre en résolu, et si un jour je veux essayer de suprimer ces variables globales, j'en ouvrirai un autre.

    Merci et à bientôt
    Avec les ordinateurs, 99% des bugs proviennent de l'interface chaise-clavier...

    Comment ça 1Km n'est pas égal à 1024m ???

  15. #15
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    Citation Envoyé par Le Mérovingien Voir le message
    @jabbounet : tu parles des Logger Java ou des singletons en général ?

    Merci à tous pour vos réponses, je me suis rappelé hier soir pourquoi j'avais besoin d'un singleton, ou d'une variable globale : mon appli est un serveur qui utilise RPC, et je n'ai pas trouvé comment passer le gestionnaire d'utilisateurs dans les fonctions que le serveur appellent : elles ont un prototype fixe qui ne prévoit pas de champs utilisateurs (void* par exemple). Si quelqu'un à la solution sans variable globale je suis preneur.

    Mais comme ce n'est pas le sujet de ce post, je vais le mettre en résolu, et si un jour je veux essayer de suprimer ces variables globales, j'en ouvrirai un autre.

    Merci et à bientôt
    Des singletons, si tu as 5 thread qui doivent écrire sur le même objet, il vont devoir se le partager par exemple ce n'est pas grave s'ils ecrivent dessus un fois tous les 10 ans. cela deviens problématque quand tu en fait plusieurs (centaine de) milliers par seconde, il s'agit souvent d'une erreur de conception à la base (le singleton n'avait pas forcement besoin d'exister, un autre choix de conception aurait été meilleur).
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  16. #16
    Membre habitué
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2005
    Messages
    147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2005
    Messages : 147
    Points : 165
    Points
    165
    Par défaut
    Oui c'est vrai, mais pour ma gestion des utilisateurs, si je passais un unique UserManger par référence, sans singleton, j'aurais le meme problème non ?
    Avec les ordinateurs, 99% des bugs proviennent de l'interface chaise-clavier...

    Comment ça 1Km n'est pas égal à 1024m ???

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

Discussions similaires

  1. Êtes-vous pour ou contre les "strict type hints" ?
    Par RideKick dans le forum Langage
    Réponses: 44
    Dernier message: 21/03/2012, 21h18
  2. Réponses: 8
    Dernier message: 03/08/2008, 23h12
  3. [travail] Pour ou contre les bureaux open-space ?
    Par Mat.M dans le forum La taverne du Club : Humour et divers
    Réponses: 31
    Dernier message: 08/04/2008, 12h58
  4. [Mapping O/R] - Pour ou contre les procédures stockées
    Par spidetra dans le forum Persistance des données
    Réponses: 8
    Dernier message: 03/04/2006, 10h01

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