Ce qui est si mal à propos de singletons? [fermé]

le singleton pattern est un membre entièrement payé du GoF s patterns book , mais il semble récemment plutôt orphelin par le monde des développeurs. J'utilise encore beaucoup de singletons, surtout pour classes d'usine , et bien que vous devez être un peu prudent sur les questions de multithreading (comme n'importe quelle classe en fait), je ne vois pas pourquoi ils sont si terribles.

Débordement De La Cheminée surtout semble supposer que tout le monde est d'accord que les Singletons sont mauvais. Pourquoi?

s'il vous Plaît soutenir vos réponses avec " des faits, des références, ou une expertise spécifique "

1767
demandé sur m87 2008-09-26 10:02:00

30 réponses

paraphrasé de Brian Button:

  1. Ils sont généralement utilisés comme une instance globale, pourquoi est-ce si mauvais? Parce que vous cachez les dépendances de votre application dans votre code, au lieu de les exposer à travers les interfaces. Faire quelque chose de global pour éviter de le passer autour est un odeur de code .

  2. ils violent le principe de responsabilité unique : en vertu du fait qu'ils contrôlent leur propre création et leur cycle de vie.

  3. ils font que le code est étroitement couplé . Cela rend la simulation sous test plutôt difficile dans de nombreux cas.

  4. ils transportent l'état pendant toute la durée de vie de l'application. Un autre hit à testing depuis que vous pouvez finir avec une situation où les tests doivent être commandés qui est un grand pas pas pour les tests unitaires. Pourquoi? Parce que chaque test unitaire doit être indépendant de l'autre.

1162
répondu Jim Burger 2016-08-09 07:30:56

Singletons résoudre un (et un seul) problème.

Les Conflits De Ressources.

si vous avez une ressource que

( 1 ) ne peut avoir qu'une seule instance, et

( 2 ) vous devez gérer cette instance unique,

vous avez besoin d'un singleton .

là ne sont pas nombreux exemples. Un fichier journal est le grand. Vous ne voulez pas abandonner un seul fichier journal. Vous voulez tirer la chasse, synchroniser et fermer correctement. Il s'agit d'un exemple de ressource partagée unique qui doit être gérée.

il est rare que vous ayez besoin d'un singleton. La raison pour laquelle ils sont mauvais est qu'ils se sentent comme un global et ils sont un membre entièrement payé de la GoF Design Patterns Livre.

quand vous pensez avoir besoin d'un global, vous faites probablement une terrible erreur de design.

408
répondu S.Lott 2015-01-15 17:55:41

certains snobs du codage les considèrent comme un glorifié global. De la même manière que beaucoup de gens détestent les goto déclaration il ya d'autres qui détestent l'idée d'utiliser un global . J'ai vu plusieurs développeurs aller à des longueurs extraordinaires pour éviter un global parce qu'ils ont considéré l'utilisation d'un comme un aveu de l'échec. Étrange, mais vrai.

dans la pratique le Singleton pattern est juste une technique de programmation qui est une partie utile de votre trousse de concepts. De temps en temps, vous pourriez trouver qu'il est la solution idéale et donc de l'utiliser. Mais l'utiliser juste pour que vous puissiez vous vanter d'utiliser un design pattern est tout aussi stupide que de refuser de l'utiliser parce que c'est juste un global .

311
répondu Phil Wright 2009-09-15 00:22:16

Misko Hevery, de Google, a quelques articles intéressants sur exactement ce sujet...

Singletons are Pathological Liars a un exemple de test unitaire qui illustre comment les singletons peuvent rendre difficile de comprendre les chaînes de dépendances et de démarrer ou tester une application. C'est un exemple assez extrême d'abus, mais l'argument qu'il avance est toujours valable:

les Singletons ne sont rien de plus que global état. L'état Global fait en sorte que vos objets puissent secrètement s'emparer de choses qui ne sont pas déclarées dans leur API, et, en conséquence, les Singletons font de votre API des menteurs pathologiques.

Where have all the Singleton Gone fait remarquer que l'injection de dépendances a rendu facile l'obtention d'instances aux constructeurs qui en ont besoin, ce qui allège le besoin sous-jacent derrière les mauvais Singleton globaux décriés dans le premier article.

202
répondu jason 2015-04-29 20:53:52

je pense que la confusion est causée par le fait que les gens ne savent pas l'application réelle du modèle Singleton. Je ne peux pas le souligner assez. Singleton est pas un motif pour envelopper globals. Singleton pattern ne doit être utilisé que pour garantir que une seule et unique instance d'une classe donnée existe pendant la durée d'exécution.

les gens pensent que Singleton est mauvais parce qu'ils l'utilisent pour les globals. C'est à cause de cette la confusion que Singleton est méprisé. S'il vous plaît, ne confondez pas Singleton et globals. S'il est utilisé dans le but pour lequel il était prévu, vous obtiendrez des avantages extrêmes du modèle Singleton.

104
répondu Cem Catikkas 2009-09-15 00:28:23

une chose assez mauvaise au sujet des singletons est que vous ne pouvez pas les étendre très facilement. Vous avez essentiellement à construire dans une sorte de motif décorateur ou une telle chose si vous voulez changer leur comportement. En outre, si un jour vous voulez avoir de multiples façons de faire une chose, il peut être assez douloureux de changer, selon la façon dont vous disposez votre code.

une chose à noter, Si vous utilisez des singletons, essayez de les passer à quiconque a besoin plutôt que de les y accéder directement... Sinon, si vous choisissez d'avoir plusieurs façons de faire ce que fait singleton, il sera plutôt difficile de changer car chaque classe intègre une dépendance si elle accède directement à singleton.

donc fondamentalement:

public MyConstructor(Singleton singleton) {
    this.singleton = singleton;
}

plutôt que:

public MyConstructor() {
    this.singleton = Singleton.getInstance();
}

je crois que ce type de modèle est appelé injection de dépendance et est généralement considéré comme une bonne chose.

comme n'importe quel modèle... Réfléchir et d'examiner si son utilisation dans la situation donnée, est inappropriée ou non... Les règles sont faites pour être brisées habituellement, et patterns ne devrait pas être appliquée délibérément sans réflexion.

71
répondu Mike Stone 2014-03-10 20:22:03

Le pattern singleton est pas un problème en soi. Le problème est que le modèle est souvent utilisé par les gens qui développent des logiciels avec des outils orientés objet sans avoir une bonne compréhension des concepts OO. Quand singletons sont introduits dans ce contexte, ils ont tendance à se développer dans des classes ingérables qui contiennent des méthodes d'aide pour chaque peu d'utilisation.

Singletons sont également un problème d'un point de vue test. Ils ont tendance à rendre les unités isolées-tests difficiles à écrire. Inversion du contrôle (IoC) et injection de dépendance sont des modèles destinés à surmonter ce problème d'une manière orientée objet qui se prête à l'essai à l'unité.

Dans un garbage collector environnement singletons peuvent rapidement devenir un problème à l'égard de la gestion de la mémoire.

Il ya aussi le scénario multi-threaded où les singletons peuvent devenir un goulot d'étranglement ainsi qu'un problème de synchronisation.

65
répondu Kimoz 2014-03-10 20:31:37

singleton " la mise en oeuvre à l'aide d'une méthode statique. Les méthodes statiques sont évitées par les personnes qui font des tests unitaires parce qu'elles ne peuvent pas être moquées ou entaillées. La plupart des gens sur ce site sont de grands partisans des tests unitaires. La convention généralement la plus acceptée pour les éviter est d'utiliser le modèle inversion of control .

52
répondu Peter Mortensen 2014-03-10 20:31:10

Singletons sont aussi mauvais quand il s'agit de clustering . Parce qu'alors, vous n'avez plus" exactement un singleton " dans votre candidature.

considérez la situation suivante: en tant que développeur, vous devez créer une application web qui accède à une base de données. Pour vous assurer que les appels de base de données concurrents ne sont pas en conflit, vous créez un thread-save SingletonDao :

public class SingletonDao {
    // songleton's static variable and getInstance() method etc. omitted
    public void writeXYZ(...){
        synchronized(...){
            // some database writing operations...
        }
    }
}

donc vous êtes sûr que seulement un singleton dans votre application existe et toute la base de données passer par celui-ci et seulement SingletonDao . Votre environnement de production ressemble maintenant à ceci: Single Singleton

tout va bien jusqu'à présent.

Maintenant, considérez que vous souhaitez configurer plusieurs instances de votre application web dans un cluster. Maintenant, vous avez soudainement quelque chose comme ceci:

Many singletons

ça semble bizarre, mais maintenant vous avez beaucoup de singleton dans votre application . Et c'est exactement ce qu'un singleton n'est pas censé être: en avoir beaucoup d'objets. Ceci est particulièrement mauvais si vous, comme montré dans cet exemple, voulez faire des appels synchronisés à une base de données.

bien sûr, c'est un exemple de mauvaise utilisation d'un singleton. Mais le message de cet exemple est le suivant: vous ne pouvez pas vous fier à ce qu'il y ait exactement une instance d'un singleton dans votre application - surtout quand elle vient de clustering.

42
répondu Uooo 2013-02-22 14:34:10
  1. Il est facile de (ab)est utilisé comme une variable globale.
  2. Les Classes
  3. qui dépendent des singletons sont relativement plus difficiles à tester en unité isolée.
34
répondu jop 2017-05-14 21:26:15

"151910920 de" Monopole "qui est le diable et les singletons avec les non-readonly/mutable état sont le "vrai" problème...

après avoir lu les Singletons sont des menteurs pathologiques comme suggéré dans la réponse de jason je suis tombé sur cette petite anecdote qui fournit le meilleur exemple présenté de comment les singletons sont souvent mal utilisés.

Global est mauvais parce que:

  • un. Il provoque l'espace de noms conflit
  • B. Il expose l'état d'une manière injustifiée

Quand il s'agit de Singletons

  • A. La façon explicite OO de les appeler, empêche les conflits, donc point a. n'est pas un problème
  • B. Les Singletons sans état (comme les usines) ne sont pas un problème. Singletons avec l'état peut à nouveau tombent dans deux catégories, ceux qui sont immuables ou écrire une fois et lire beaucoup (fichiers de configuration/propriétés). Ce ne sont pas mauvais. Les Singletons mutables, qui sont en quelque sorte des supports de référence, sont ceux dont vous parlez.

dans sa dernière déclaration, il fait référence au concept du blog "Singleton are liars".

comment cela s'applique-t-il au monopole?

pour commencer une partie de monopole, d'abord:

  • nous établissons les règles d'abord pour que tout le monde soit sur la même page
  • tout le monde est sur un pied d'égalité dès le début du jeu
  • un seul ensemble de règles est présenté pour éviter la confusion
  • les règles ne sont pas autorisés à changer tout au long du jeu

maintenant, pour quiconque n'a pas vraiment a joué le monopole, ces normes sont idéales au mieux. Une défaite dans le monopole est difficile à avaler parce que, le monopole est une question d'argent, si vous perdez, vous devez regarder avec soin le reste des joueurs terminer le jeu, et les pertes sont généralement rapides et écrasant. Ainsi, les règles sont habituellement tordues à un certain point pour servir l'intérêt personnel de certains joueurs aux dépens des autres.

donc vous jouez au monopoly avec vos amis Bob, Joe et Ed. Vous construisez rapidement votre empire et consommer des parts de marché à un rythme exponentiel. Vos adversaires s'affaiblissent et vous commencez à sentir le sang (figurativement). Votre ami Bob a investi tout son argent dans la mise en réserve d'autant de propriétés de faible valeur que possible, mais il ne reçoit pas un rendement élevé de l'investissement comme il s'y attendait. Bob, comme un coup de malchance, atterrit sur votre promenade et est retiré du jeu.

maintenant, le jeu passe de amical dés-rouler à des affaires sérieuses. Bob a été fait l'exemple de l'échec et Joe et Ed ne veux pas finir comme 'gars'. En tant que joueur principal, vous devenez soudainement l'ennemi. Joe et Ed commencent à s'entraîner à faire des transactions en dessous de la table, à faire des injections d'argent derrière le dos, à sous-évaluer le house-swapping et généralement n'importe quoi pour vous affaiblir en tant que joueur jusqu'à ce que l'un d'eux monte au sommet.

alors, au lieu de l'un d'eux gagnant, le processus commence partout. Tout d'un coup, d'un ensemble fini de règles devient une cible en mouvement et le jeu dégénère dans le type d'interactions sociales qui constitueraient la base de chaque émission de télé-réalité de haut niveau depuis Survivor. Pourquoi, parce que les règles changent et qu'il n'y a pas de consensus sur la façon, la raison et ce qu'elles sont censées représenter, et plus important encore, il n'y a pas une seule personne qui prend les décisions. Chaque joueur dans le jeu, à ce moment-là, fait ses propres règles et le chaos s'ensuit jusqu'à ce que deux des joueurs sont trop fatigués pour garder la charade et abandonner lentement.

ainsi, si un livre de règles pour un jeu représentait avec précision un singleton, le monopoly rulebook serait un exemple d'abus.

Comment cela s'applique à la programmation?

mis à part tous les problèmes évidents de sécurité du fil et de synchronisation que présentent les singletons mutables... Si vous avez un ensemble de données, qui est capable d'être lu/manipulé par de multiples sources différentes simultanément et existe au cours de la vie de l'exécution de l'application, il est probablement un bon moment pour prendre du recul et demander "Est-ce que j'utilise le bon type de structure de données ici".

personnellement, j'ai vu un programmeur abuser un singleton en l'utilisant comme une sorte de magasin de base de données à fil croisé tordu dans une application. Après avoir travaillé directement sur le code, je peux attester que c'était un lent (à cause de tous les verrous de thread nécessaires pour le rendre fil-safe) et un cauchemar à travailler sur (à cause de la nature imprévisible / intermittente des bogues de synchronisation), et presque impossible à tester dans des conditions de "production". Bien sûr, un système aurait pu être développé en utilisant le sondage/la signalisation pour surmonter certains problèmes de performance, mais cela ne résoudrait pas les problèmes avec les tests et, pourquoi s'embêter quand une "vraie" base de données peut déjà accomplir la même fonctionnalité d'une manière beaucoup plus robuste/évolutive.

d'Un Singleton est seulement une option si vous avez besoin de ce que fournit un singleton. Une instance écrite-une instance en lecture seule d'un objet. Cette même règle devrait également s'appliquer aux propriétés/membres de l'objet.

30
répondu Evan Plaice 2017-05-23 12:26:27

Singleton ne parle pas d'instance unique!

Contrairement aux autres réponses, Je ne veux pas parler de ce qui ne va pas avec les Singletons, mais pour vous montrer à quel point ils sont puissants et géniaux lorsqu'ils sont utilisés correctement!

  • Problème : Singleton peut être un défi dans le multi-threading environnement

    Solution : Utiliser un seul thread processus de démarrage pour initialiser tous les les dépendances de votre singleton.
  • problème : il est difficile de se moquer des singletons.

    Solution : Utilisez la méthode Usine motif de moquerie

    MyModel myModel = Factory.inject(MyModel.class); Vous pouvez associer MyModel à TestMyModel classe qui en hérite, partout où MyModel sera injecté vous obtiendrez TestMyModel Instaread.
  • Problème : les Singletons peuvent causer des poireaux de mémoire comme ils n'ont jamais disposé.

    Solution : Eh bien, jetez-les! Implémenter un callback dans votre application pour disposer correctement d'un singleton, vous devez supprimer toutes les données qui y sont liées et enfin: les supprimer de l'usine.

comme je l'ai dit au titre singleton ne sont pas sur une instance simple.

  • Singletons améliore la lisibilité : vous pouvez regarder votre classe et voir ce singleton il a injecté pour comprendre ce que c'est des dépendances.
  • Singletons améliore la maintenance : une fois que vous avez supprimé une dépendance d'une classe, vous venez de supprimer une injection de singleton, vous n'avez pas besoin d'aller et éditer un grand lien d'autres classes qui vient de déplacer votre dépendance autour(c'est le code malodorant pour moi @Jim Burger )
  • Singletons améliore la mémoire et la performance : quand quelque chose se produit dans votre application, et il faut une longue chaîne de callbacks à livrer, vous gaspillez la mémoire et la performance, en utilisant Singleton vous coupez l'homme moyen, et améliorer votre performance et l'utilisation de la mémoire(en évitant les allocations de variables locales inutiles).
22
répondu Ilya_Gazman 2017-05-23 12:03:07

Ma réponse sur la façon dont les Singletons sont mauvais est toujours, "ils sont difficiles à faire". Beaucoup des composants de base des langages sont des singletons (classes, fonctions, namespaces et même opérateurs), comme le sont les composants d'autres aspects de l'informatique (localhost, route par défaut, Système de fichiers virtuel, etc.), et ce n'est pas par accident. Pendant qu'ils causent des problèmes et de la frustration, de temps à autre, ils peuvent aussi faire beaucoup de choses fonctionnent BEAUCOUP mieux.

les deux plus grosses vis les ups que je vois sont: le traiter comme un global et ne pas définir la fermeture Singleton.

tout le monde parle de Singleton comme des globals, parce qu'ils le sont fondamentalement. Cependant, beaucoup (malheureusement, pas tous) de la méchanceté dans un mondial vient pas intrinsèquement d'être mondial, mais la façon dont vous l'utiliser. En va de même pour les Singletons. En fait plus comme " instance unique "n'a vraiment pas besoin de signifier"globalement accessible". C'est plus un sous-produit naturel, et étant donné tout le mal que nous savons vient de nous ne devrions pas être si pressés d'exploiter l'accessibilité mondiale. Une fois que les programmeurs voient un Singleton, ils semblent toujours y accéder directement par sa méthode d'instance. Au lieu de cela, vous devriez y naviguer comme vous le feriez pour n'importe quel autre objet. La plupart du code ne devrait même pas savoir qu'il s'agit d'un simple couplage, non?). Si seulement un petit bout de code accède à l'objet comme s'il était global, beaucoup de dommages sont annulés. Je recommande de l'appliquer en limitant l'accès à l'instance fonction.

le contexte Singleton est également très important. La caractéristique déterminante d'un Singleton est qu'il n'y en a "qu'un", mais la vérité est qu'il n'y en a "qu'un" dans une sorte de contexte/namespace. Ils sont généralement un de: un par thread, processus, adresse IP ou cluster, mais peut également être un par processeur, machine, langue namespace/class loader/whatever, subnet, Internet, etc.

l'autre, moins commune, l'erreur est d'ignorer le Singleton vie. Ce n'est pas parce qu'il n'y en a qu'un que cela signifie qu'un Singleton est un omnipotent "qui a toujours été et qui le sera toujours", pas plus qu'il n'est généralement souhaitable (les objets sans début et sans fin violent toutes sortes d'hypothèses utiles dans le code, et ne devraient être employés que dans les circonstances les plus désespérées.

si vous évitez ces erreurs, Singletons peuvent encore être une PITA, bit il est prêt à voir beaucoup des pires problèmes sont atténués de manière significative. Imaginez un Java Singleton, qui est explicitement défini comme une fois par classloader (ce qui signifie qu'il a besoin d'une politique de sécurité du thread), avec des méthodes de création et de destruction définies et un cycle de vie qui dicte quand et comment elles sont invoquées, et dont la méthode "instance" a une protection de paquet de sorte qu'elle est généralement accessible par d'autres objets non globaux. Encore une source potentielle de problèmes, mais certainement beaucoup moins de problèmes.

malheureusement, plutôt que d'enseigner de bons exemples de la façon de faire des Singletons. Nous enseignons mauvais exemples, laissez les programmeurs les utiliser pendant un certain temps, puis dites-leur qu'ils sont un mauvais modèle de conception.

20
répondu Christopher Smith 2014-03-10 20:42:38

Voir Wikipedia Singleton_pattern

il est également considéré comme un modèle anti-modèle par certaines personnes, qui estiment qu'il est trop utilisé, introduisant des limitations inutiles dans les situations où une seule instance d'une classe n'est pas réellement nécessaire.[1][2][3][4]

Références (uniquement sur les références de l'article)

  1. ^ Alex Miller. Patterns Je déteste # 1: Singleton , juillet 2007
  2. ^ Scott Densmore. Pourquoi les singletons sont mal , Mai 2004
  3. ^ Steve Yegge. Singletons considéré comme stupide , septembre 2004
  4. ^ J. B. Rainsberger, IBM. Utilisez vos singletons sagement , juillet 2001
20
répondu GUI Junkie 2016-04-08 09:19:24

ce n'est pas que les singletons eux-mêmes sont mauvais, mais le design GoF l'est. Le seul argument valable est que le modèle de conception GoF ne se prête pas aux essais, surtout si les essais sont effectués en parallèle.

utiliser une seule instance d'une classe est une construction valide aussi longtemps que vous appliquez les moyens suivants dans le code:

  1. assurez-vous que la classe qui sera utilisée comme un singleton interface. Cela permet de mettre en œuvre des talons ou des mocks en utilisant la même interface

  2. assurez-vous que le Singleton est sans fil. C'est une donnée.

  3. Le singleton doit être de nature simple et pas trop compliqué.

  4. pendant l'exécution de votre application, où les singletons doivent être passés à un objet donné, utilisez une usine de classe qui construit que objet et demandez à la classe de l'usine de passer à l'instance du singleton de la classe qui en a besoin.

  5. pendant les tests et pour assurer un comportement déterministe, créer la classe singleton comme instance séparée soit comme la classe actuelle elle-même, soit comme un BUB/mock qui implémente son comportement et le passe comme il est à la classe qui l'exige. N'utilisez pas le facteur de classe qui crée l'objet sous test qui a besoin du singleton pendant le test car il va passer le simple exemple global de cela, qui va à l'encontre du but.

nous avons utilisé des Singletons dans nos solutions avec beaucoup de succès qui sont testables en assurant le comportement déterministe dans les flux d'essais parallèles.

16
répondu 2 revs, 2 users 92%user1578119 2012-08-12 16:48:35

Vince Huston a ces critères, ce qui semble raisonnable pour moi:

Singleton ne doit être pris en considération que si les trois critères suivants sont remplis:

  • la propriété de l'instance unique ne peut pas être raisonnablement cédée
  • L'initialisation paresseuse est souhaitable
  • Global accès n'est pas prévue pour les

Si la propriété de l'instance unique, quand et comment l'initialisation se produit, et sur le monde ne sont pas des questions, Singleton n'est pas suffisamment intéressant.

15
répondu js. 2009-11-23 09:58:11

j'aimerais aborder les 4 points dans la réponse acceptée, avec un peu de chance quelqu'un peut expliquer pourquoi je me trompe.

  1. pourquoi cacher des dépendances dans votre code est mauvais? Il existe déjà des douzaines de dépendances cachées (appels C runtime, appels API OS, appels de fonctions globales), et les dépendances singleton sont faciles à trouver (search for instance()).

    " faire quelque chose de global pour éviter de le passer est une odeur de code."Pourquoi n'est-ce pas passer quelque chose pour éviter d'en faire une odeur de code?

    si vous passez un objet à travers 10 fonctions dans une pile d'appels juste pour éviter un singleton, est-ce si grand?

  2. principe de Responsabilité Unique: je pense que c'est un peu vague et dépend de votre définition de la responsabilité. Une question pertinente serait celle-ci: pourquoi ajouter ce spécifique responsabilité "à une matière de classe?

  3. pourquoi le fait de passer un objet à une classe le rend-il plus étroitement couplé que l'utilisation de cet objet comme un singleton de l'intérieur de la classe?

  4. pourquoi change-t-il la durée de l'état? Les Singletons peuvent être créés ou détruits manuellement, donc le contrôle est toujours là, et vous pouvez rendre la durée de vie la même que celle d'un objet non-singleton.

En ce qui concerne les essais unitaires:

  • toutes les classes ne doivent pas nécessairement être unitaires testé
  • pas toutes les classes qui doivent être unitaires testé besoin de changer la mise en œuvre de la loi unique 1519100920"
  • s'ils do doivent être soumis à un essai à l'unité et avez besoin de changer la mise en œuvre, il est facile de modifier une classe de utiliser un singleton pour avoir le singleton transmises via dépendance injection.
14
répondu Jon 2010-04-07 13:31:48

Je ne vais pas commenter l'argument du bien/mal, mais je ne les ai pas utilisés depuis que printemps est arrivé. L'utilisation de dependency injection a pratiquement éliminé mes besoins pour singleton, les localisateurs de service et les usines. Je trouve que c'est un environnement beaucoup plus productif et propre, au moins pour le type de travail que je fais (applications Web basées sur Java).

13
répondu Peter Mortensen 2014-03-10 20:37:38

les Singleton sont mauvais d'un point de vue puriste.

à Partir d'une pratique de point de vue, d'un singleton est un compromis temps de développement vs complexité .

si vous savez que votre application ne changera pas beaucoup, ils sont assez OK pour aller avec. Il suffit de savoir que vous pouvez avoir besoin de reformuler les choses si vos exigences changent d'une manière inattendue (ce qui est assez bien dans la plupart des cas).

Singletons sometimes aussi compliquer tests unitaires .

12
répondu tacone 2014-03-10 20:40:06

Il n'y a rien d'intrinsèquement mauvais avec le patron, en supposant qu'il est utilisé pour certains aspects du modèle qui est vraiment unique.

je crois que le contrecoup est dû à sa surutilisation qui, à son tour, est due au fait que c'est le modèle le plus facile à comprendre et à mettre en œuvre.

11
répondu Ben Hoffstein 2008-09-26 06:07:41

Singleton est un modèle et peut être utilisé ou abusé comme n'importe quel autre outil.

La mauvaise partie d'un singleton est généralement l'utilisateur (ou devrais-je dire l'utilisation inappropriée d'un singleton pour des choses qu'il n'est pas conçu pour). Le plus grand délinquant utilise un singleton comme une fausse variable globale.

11
répondu Loki Astari 2014-03-10 20:40:59

quand vous écrivez du code en utilisant des singletons, par exemple, un logger ou une connexion à une base de données, et qu'ensuite vous découvrez que vous avez besoin de plus d'un log ou de plus d'une base de données, vous êtes en difficulté.

Les Singletons

rendent très difficile leur déplacement vers des objets réguliers.

aussi, il est trop facile d'écrire un singleton non-thread-safe.

plutôt que d'utiliser des singletons, vous devez passer tous les objets utilitaires nécessaires de la fonction à fonction. Cela peut être simplifié si vous les enveloppez tous dans un objet helper, comme ceci:

void some_class::some_function(parameters, service_provider& srv)
{
    srv.get<error_logger>().log("Hi there!");
    this->another_function(some_other_parameters, srv);
}
8
répondu Roman Odaisky 2008-09-26 06:20:10

Les problèmes avec les singletons est la question de l'accroissement de la portée et, par conséquent, couplage . Il est indéniable qu'il existe certaines situations où vous avez besoin d'accéder à une instance unique, et cela peut être accompli d'autres façons.

maintenant, je préfère le design autour d'un inversion de contrôle (Cio) de conteneur et de permettre à la à la durée de vie pour être contrôlé par le conteneur. Cela vous donne l'avantage de classes en fonction de l'instance ne pas être conscients du fait qu'il existe une seule instance. La vie du singleton peut être changée dans le futur. Un exemple que j'ai rencontré récemment était un ajustement facile de fil simple à multi-filetés.

FWIW, si c'est une PIA lorsque vous essayez de test de l'unité, puis il va PIA lorsque vous essayez de déboguer, correction de bug ou de l'améliorer.

7
répondu Mark Lindell 2014-03-10 20:53:40

article Récent sur ce sujet par Chris Reath à Codage Sans Commentaires .

Note: le codage Sans commentaires n'est plus valide. Cependant, l'article auquel il est lié a été cloné par un autre utilisateur.

http://geekswithblogs.net/AngelEyes/archive/2013/09/08/singleton-i-love-you-but-youre-bringing-me-down-re-uploaded.aspx

7
répondu stephenbayer 2014-09-30 18:43:46

Voici encore une chose au sujet des singletons que personne n'a dit encore.

dans la plupart des cas" singletonity " est un détail de mise en œuvre pour une classe plutôt que caractéristique de son interface. L'Inversion du conteneur de contrôle peut cacher cette caractéristique aux utilisateurs de classe; vous avez juste besoin de marquer votre classe comme un singleton (avec @Singleton annotation en Java par exemple) et c'est tout; IoCC fera le reste. Vous n'avez pas besoin de fournir un accès global à votre singleton exemple parce que l'accès est déjà géré par IoCC. Il n'y a donc rien de mal à ce Qu'il y ait des Singletons du CIO.

GoF Singletons à l'opposé du Cio, les Singletons sont censés exposer "singletonity" dans l'interface par le biais de méthode getInstance (), et qu'ils souffrent de tout ce qui est dit ci-dessus.

6
répondu Volodymyr Frolov 2010-06-01 21:29:40

les Singleton ne sont pas mauvais. C'est seulement mauvais quand vous faites quelque chose globalement unique qui n'est pas globalement unique.

cependant, il y a" application scope services "(pensez à un système de messagerie qui fait interagir les composants) - cela nécessite un singleton, une" MessageQueue "- classe qui a une méthode " SendMessage(...)".

vous pouvez alors faire ce qui suit de partout:

MessageQueue.Actuel.SendMessage (nouveau MailArrivedMessage(...));

et, bien sûr, faire:

MessageQueue.Actuel.RegisterReceiver (this);

dans les classes qui implémentent IMessageReceiver.

6
répondu StormianRootSolver 2010-06-05 10:42:47

trop de gens mettent des objets qui ne sont pas filés en sécurité dans un modèle de singleton. J'ai vu des exemples d'un Datacontexte ( LINQ à SQL ) fait dans un modèle de singleton, malgré le fait que le Datacontexte N'est pas thread sûr et est purement une unité de travail objet.

6
répondu Peter Mortensen 2014-03-10 20:44:42

parce que ce sont essentiellement des variables globales orientées objet, vous pouvez généralement concevoir vos classes de telle manière que vous n'en ayez pas besoin.

4
répondu Ycros 2008-09-26 06:05:36

un modèle apparaît lorsque plusieurs personnes (ou équipes) arrivent à des solutions similaires ou identiques. Beaucoup de gens utilisent encore des singletons dans leur forme originale ou en utilisant des gabarits d'usine (bonne discussion dans le Design moderne c++ D'Alexandrescu). La concurrence et la difficulté de gérer la durée de vie de l'objet sont les principaux obstacles, avec les premiers facilement gérés comme vous le suggérez.

comme tous les choix, Singleton a sa part de hauts et de bas. Je pense qu'ils peuvent être utilisé avec modération, en particulier pour les objets qui survivent à la durée de vie de l'application. Le fait qu'ils ressemblent (et probablement) globals ont probablement déclencher les puristes.

4
répondu user22044 2008-09-26 06:14:25

tout d'abord, une classe et ses collaborateurs doivent d'abord réaliser leur but visé plutôt que de se concentrer sur les "déoendents". La gestion du cycle de vie (lorsqu'il y a des cas de non-respect de la portée) ne devrait pas faire partie de la responsabilité des cladses. La meilleure pratique acceptée pour cela est d'élaborer ou de configurer un nouveau composant pour gérer les dépendances en utilisant l'injection de dépendances.

souvent le logiciel devient plus compliqué il est logique d'avoir plusieurs instances indépendantes de la classe "singleton" avec un état différent. Dans de tels cas, il est erroné d'utiliser le code pour saisir simplement le singleton. En Utilisant Singleton.gettinstance () peut être correct pour les petits systèmes simples, mais il ne fonctionne pas quand on a besoin d'une instance différente de la même classe.

aucune classe ne doit être considérée comme un singleton mais plutôt comme une application de son usage ou de la façon dont il est utilisé pour configurer les personnes à charge. Pour un rapide et Méchant ce n'est pas matter-juste luke hardcoding dire que les chemins de fichier n'a pas d'importance, mais pour les applications plus grandes telles dépendances doivent être prises en compte et gérées de manière plus appropriée en utilisant DI.

les problèmes que singleton cause dans les tests est un symptôme de leur cas d'usage simple codé dur/environnement. La suite de tests et les nombreux tests sont chacun individuels et séparés quelque chose qui n'est pas compatible avec le codage dur d'un singleton.

4
répondu mP. 2009-04-28 01:14:39