Le motif de singleton est membre entièrement libérées de la GoF d » motifs livre , mais il semble ces derniers temps plutôt rendus orphelins par le monde des développeurs. J'utilise encore pas mal de singletons, en particulier pour les classes d'usine , et bien que vous deviez faire un peu attention aux problèmes de multithreading (comme n'importe quelle classe en fait), je ne vois pas pourquoi ils sont si horribles.
Stack Overflow semble surtout supposer que tout le monde convient que les singletons sont mauvais. Pourquoi?
Veuillez étayer vos réponses par des « faits, références ou expertise spécifique »
Réponses:
Paraphrasé de Brian Button:
Ils sont généralement utilisés comme une instance globale, pourquoi est-ce si mauvais? Parce que vous masquez les dépendances de votre application dans votre code, au lieu de les exposer via les interfaces. Faire quelque chose de global pour éviter de le faire passer est une odeur de code .
Ils violent le principe de la responsabilité unique : du fait qu'ils contrôlent leur propre création et cycle de vie.
Ils provoquent par nature un couplage étroit du code . Cela rend leur simulation sous test assez difficile dans de nombreux cas.
Ils portent l'état pendant toute la durée de vie de l'application. Un autre succès pour les tests car vous pouvez vous retrouver avec une situation où les tests doivent être commandés, ce qui est un gros non pour les tests unitaires. Pourquoi? Parce que chaque test unitaire doit être indépendant de l'autre.
la source
Les singletons résolvent un (et un seul) problème.
Contention de ressources.
Si vous avez une ressource qui
( 1 ) ne peut avoir qu'une seule instance, et
( 2 ) vous devez gérer cette seule instance,
vous avez besoin d'un singleton .
Il n'y a pas beaucoup d'exemples. Un fichier journal est le gros. Vous ne voulez pas simplement abandonner un seul fichier journal. Vous souhaitez vider, synchroniser et fermer correctement. Ceci est un exemple d'une 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, c'est qu'ils se sentent comme un global et qu'ils sont un membre à part entière du livre GoF Design Patterns .
Lorsque vous pensez que vous avez besoin d'un global, vous faites probablement une terrible erreur de conception.
la source
Certains snobs de codage les considèrent comme un simple monde glorifié. De la même manière que beaucoup de gens détestent la déclaration goto , il y en a d'autres qui détestent l'idée de jamais utiliser un global . J'ai vu plusieurs développeurs faire des efforts extraordinaires pour éviter un global car ils considéraient en utiliser un comme un aveu d'échec. Etrange mais vrai.
En pratique, le modèle Singleton n'est qu'une technique de programmation qui est une partie utile de votre boîte à outils de concepts. De temps en temps, vous pourriez trouver que c'est la solution idéale et donc l'utiliser. Mais l'utiliser juste pour que vous puissiez vous vanter d'utiliser un modèle de conception est tout aussi stupide que de ne jamais l'utiliser parce que c'est juste un global .
la source
Misko Hevery, de Google, a des articles intéressants sur exactement ce sujet ...
Les singletons sont des menteurs pathologiques a un exemple de test unitaire qui illustre comment les singletons peuvent rendre difficile la détermination des chaînes de dépendance et le démarrage ou le test d'une application. C'est un exemple assez extrême d'abus, mais l'argument qu'il fait est toujours valable:
Là où tous les singletons sont partis, le fait que l'injection de dépendances a facilité l'obtention des instances aux constructeurs qui en ont besoin, ce qui atténue le besoin sous-jacent derrière les mauvais singletons mondiaux décriés dans le premier article.
la source
Je pense que la confusion est causée par le fait que les gens ne connaissent pas la véritable application du modèle Singleton. Je ne saurais trop insister sur ce point. Singleton n'est pas un modèle pour envelopper les mondiaux. Le modèle singleton ne doit être utilisé que pour garantir qu'une et une seule instance d'une classe donnée existe pendant l'exécution.
Les gens pensent que Singleton est mauvais parce qu'ils l'utilisent pour les mondiaux. C'est à cause de cette confusion que Singleton est méprisé. S'il vous plaît, ne confondez pas singletons et globaux. S'il est utilisé dans le but pour lequel il a été conçu, vous tirerez des avantages extrêmes du modèle Singleton.
la source
setInstance
méthodes.) état mondial mutable, alors il a utilement (?) fourni des poseurs pour tous. Célibataire. champ. (Et oui, cela arrive. Beaucoup . Presque tous les singleton que j'ai jamais vus dans la nature étaient mutables par conception, et souvent de manière embarrassante.)goto
etc. Ils peuvent fonctionner dans de nombreux cas, mais franchement, "ça marche" ne suffit pas - si vous voulez aller à l'encontre de la sagesse conventionnelle, vous feriez mieux de pouvoir démontrer comment votre approche est meilleur que les solutions conventionnelles. Et je n'ai pas encore vu un tel cas pour le motif Singleton.getInstance
méthode ou un nom similaire, et empêche l'existence d'un deuxième instance. Franchement, à ce stade, vous pourriez tout aussi bien ne pas avoir la seule instance.Une mauvaise chose à propos des singletons est que vous ne pouvez pas les étendre très facilement. Vous devez essentiellement construire une sorte de motif de décoration ou quelque chose de ce genre si vous voulez changer leur comportement. De plus, si un jour vous voulez avoir plusieurs façons de faire cette chose, cela 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 transmettre à ceux qui en ont besoin plutôt que de les faire accéder directement ... Sinon, si vous choisissez d'avoir plusieurs façons de faire la chose que singleton fait, ce sera assez difficile à changer car chaque classe incorpore une dépendance si elle accède directement au singleton.
Donc en gros:
plutôt que:
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 tout modèle cependant ... Pensez-y et demandez-vous si son utilisation dans la situation donnée est inappropriée ou non ... Les règles sont faites pour être brisées généralement, et les modèles ne doivent pas être appliqués volontairement sans réfléchir.
la source
getInstance()
, alors (b) n'est plus tout à fait vrai.getInstance()
, vous avez effectivement éliminé la seule différence utile entre le modèle Singleton et une référence ordinaire. Pour le reste du code, l'unicité n'est plus une propriété. Seul l'appelant agetInstance()
besoin de savoir ou même de se soucier du nombre d'instances. Avec un seul appelant, il en coûte plus d'efforts et de flexibilité pour que la classe applique de manière fiable l'unicité que pour que l'appelant stocke simplement une référence et la réutilise.Le motif singleton n'est pas un problème en soi. Le problème est que le modèle est souvent utilisé par les personnes développant des logiciels avec des outils orientés objet sans avoir une solide compréhension des concepts OO. Lorsque des singletons sont introduits dans ce contexte, ils ont tendance à se transformer en classes ingérables qui contiennent des méthodes d'assistance pour chaque petite utilisation.
Les singletons sont également un problème du point de vue des tests. Ils ont tendance à rendre les tests unitaires isolés difficiles à écrire. L'inversion de contrôle (IoC) et l' injection de dépendances sont des modèles destinés à surmonter ce problème d'une manière orientée objet qui se prête aux tests unitaires.
Dans un environnement poubelle, les singletons peuvent rapidement devenir un problème de gestion de la mémoire.
Il existe également le scénario multi-thread où les singletons peuvent devenir un goulot d'étranglement ainsi qu'un problème de synchronisation.
la source
Un singleton est implémenté à l'aide d'une méthode statique. Les personnes qui font des tests unitaires évitent les méthodes statiques car elles ne peuvent pas être moquées ou écrasé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 l' inversion du modèle de contrôle .
la source
Singleton
classe. Cependant, cela complique énormément le processus de test. D'une part, vous devez maintenant pouvoir décharger les classes à volonté (ce n'est pas vraiment une option dans la plupart des langues), ou démarrer une nouvelle machine virtuelle pour chaque test (lire: les tests peuvent prendre des milliers de fois plus longtemps). Pour deux, cependant, la dépendanceSingleton
est un détail d'implémentation qui fuit maintenant partout dans vos tests.Les singletons sont également mauvais en matière de clustering . Parce qu'alors, vous n'avez plus "exactement un singleton" dans votre application.
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 simultanés n'entrent pas en conflit, vous créez un thread-save
SingletonDao
:Vous êtes donc sûr qu'il n'existe qu'un seul singleton dans votre application et que toutes les bases de données passent par celui-ci et seulement
SingletonDao
. Votre environnement de production ressemble maintenant à ceci: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 soudain quelque chose comme ça:
Cela semble bizarre, mais maintenant vous avez beaucoup de singletons dans votre application . Et c'est exactement ce qu'un singleton n'est pas censé être: en avoir beaucoup d'objets. Cela est particulièrement mauvais si vous, comme indiqué dans cet exemple, souhaitez effectuer des appels synchronisés vers une base de données.
Bien sûr, ceci est un exemple d'une mauvaise utilisation d'un singleton. Mais le message de cet exemple est le suivant: vous ne pouvez pas compter qu'il existe exactement une instance d'un singleton dans votre application, en particulier en ce qui concerne le clustering.
la source
la source
Le monopole est le diable et les singletons avec un état non en lecture seule / mutable 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 friandise qui fournit le meilleur exemple présenté de la façon dont les singletons sont souvent mal utilisés.
Dans la dernière déclaration, il fait référence au concept du blog de «singletons sont des menteurs».
Comment cela s'applique-t-il au monopole?
Pour commencer un jeu de monopole, d'abord:
Maintenant, pour quiconque n'a pas vraiment joué le monopole, ces normes sont au mieux idéales. Une défaite en monopole est difficile à avaler car, le monopole est une question d'argent, si vous perdez, vous devez regarder attentivement le reste des joueurs terminer le jeu, et les pertes sont généralement rapides et écrasantes. Ainsi, les règles sont généralement tordues à un moment donné pour servir les intérêts personnels de certains joueurs au détriment des autres.
Vous jouez donc en monopole avec des amis Bob, Joe et Ed. Vous construisez rapidement votre empire et consommez des parts de marché à un rythme exponentiel. Vos adversaires s'affaiblissent et vous commencez à sentir le sang (au sens figuré). Votre copain Bob a investi tout son argent dans le blocage du plus grand nombre possible de propriétés de faible valeur, mais le sien ne reçoit pas un retour sur investissement élevé comme il s'y attendait. Bob, comme un coup de malchance, atterrit sur votre Boardwalk et est retiré du jeu.
Maintenant, le jeu passe du lancer de dés amical aux affaires sérieuses. Bob est devenu un exemple d'échec et Joe et Ed ne veulent pas finir comme «ce gars». Donc, étant le principal acteur, vous devenez tout d'un coup l'ennemi. Joe et Ed commencent à pratiquer des échanges sous la table, des injections d'argent dans le dos, des échanges de maisons sous-évalués et généralement tout ce qui vous affaiblit en tant que joueur jusqu'à ce que l'un d'eux atteigne le sommet.
Puis, au lieu que l'un d'eux gagne, le processus recommence. Tout d'un coup, un ensemble fini de règles devient une cible mouvante et le jeu dégénère en le type d'interactions sociales qui constitueraient le fondement 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 comment / pourquoi / ce qu'elles sont censées représenter, et plus important encore, il n'y a personne pour prendre les décisions. À ce stade, chaque joueur du jeu établit ses propres règles et le chaos s'ensuit jusqu'à ce que deux des joueurs soient trop fatigués pour continuer la mascarade et abandonner lentement.
Donc, si un livre de règles pour un jeu représentait fidèlement un singleton, le livre de règles monopolistique serait un exemple d'abus.
Comment cela s'applique-t-il à la programmation?
Mis à part tous les problèmes évidents de sécurité des threads et de synchronisation que les singletons mutables présentent ... c'est probablement le 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 d'un singleton en l'utilisant comme une sorte de magasin de base de données cross-thread torsadé dans une application. Ayant travaillé directement sur le code, je peux attester qu'il s'agissait d'un ralentissement (en raison de tous les verrous de threads nécessaires pour le rendre sûr pour les threads) et d'un cauchemar sur lequel travailler (en raison 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 l'interrogation / signalisation pour surmonter certains des problèmes de performances, 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é dans un environnement beaucoup plus robuste / de manière évolutive.
Un Singleton est seulement une option si vous avez besoin ce qu'un singleton fournit. Une instance en lecture seule en écriture d'un objet. Cette même règle doit également se connecter aux propriétés / membres de l'objet.
la source
Singleton.getInstance()
. Un langage qui prend en charge la réflexion peut être en mesure de contourner cela en définissant le champ où la One True Instance est stockée. IMO, cependant, les tests deviennent un peu moins dignes de confiance une fois que vous vous êtes familiarisé avec l'état privé d'une autre classe.Singleton n'est pas une instance unique!
Contrairement à d'autres réponses, je ne veux pas parler de ce qui ne va pas avec les singletons, mais vous montrer à quel point ils sont puissants et impressionnants lorsqu'ils sont bien utilisés!
Solution : Utilisez un processus d'amorçage à thread unique pour initialiser toutes les dépendances de votre singleton.
Solution : utilisez la méthode Modèle d' usine pour se moquer
Vous pouvez mapper
MyModel
à laTestMyModel
classe qui en hérite, partout oùMyModel
sera injecté vous obtiendrezTestMyModel
instread. - Problème : les singletons peuvent provoquer des fuites de mémoire car ils n'ont jamais été éliminés.Solution : Eh bien, jetez-les! Implémentez un rappel dans votre application pour éliminer correctement les singletons, vous devez supprimer toutes les données qui leur sont liées et enfin: les supprimer de l'usine.
Comme je l'ai dit au titre, le singleton ne concerne pas une seule instance.
la source
Settings
objet singleton qui est accessible à partir de n'importe quel widget afin que chaque widget sache comment formater les nombres affichés. Si ce n'était pas un objet accessible globalement, je devrais l'injecter dans le constructeur à chaque widget du constructeur et garder la référence à lui en tant que variable membre. C'est une terrible perte de mémoire et de temps.Ma réponse sur la façon dont les singletons sont mauvais est toujours "ils sont difficiles à bien faire". De nombreux composants fondamentaux des langages sont des singletons (classes, fonctions, espaces de noms et même opérateurs), tout comme les composants d'autres aspects de l'informatique (hôte local, route par défaut, système de fichiers virtuel, etc.), et ce n'est pas par accident. Bien qu'ils causent des ennuis et de la frustration de temps en temps, ils peuvent aussi améliorer beaucoup de choses.
Les deux plus gros défauts que je vois sont: le traiter comme un global et ne pas définir la fermeture de Singleton.
Tout le monde parle de Singleton en tant que globaux, car ils le sont essentiellement. Cependant, une grande partie (malheureusement, pas tous) de la méchanceté dans un global ne vient pas intrinsèquement d'être global, mais de la façon dont vous l'utilisez. Il en va de même pour les singletons. En fait, d'autant plus que "instance unique" n'a pas vraiment besoin de signifier "globalement accessible". C'est plus un sous-produit naturel, et étant donné tout le mal que nous savons en provient, 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 via sa méthode d'instance. Au lieu de cela, vous devez y accéder comme vous le feriez pour tout autre objet. La plupart des codes ne devraient même pas être conscients qu'il s'agit d'un Singleton (couplage lâche, non?). Si seulement un petit morceau de code accède à l'objet comme s'il s'agissait d'un global, beaucoup de dommages sont annulés.
Le contexte Singleton est également très important. La caractéristique qui définit un Singleton est qu'il n'y en a "qu'un", mais la vérité est qu'il n'est "qu'un" dans une sorte de contexte / espace de noms. Ils sont généralement l'un des: un par thread, processus, adresse IP ou cluster, mais peut également être un par processeur, machine, espace de noms de langage / chargeur de classe / autre, sous-réseau, Internet, etc.
L'autre erreur, moins courante, est d'ignorer le mode de vie Singleton. Le simple fait qu'il n'y en ait qu'un ne signifie pas qu'un Singleton est omnipotent "a toujours été et sera toujours", et n'est généralement pas souhaitable (les objets sans début ni fin violent toutes sortes d'hypothèses utiles dans le code et ne doivent être utilisés que dans les circonstances les plus désespérées.
Si vous évitez ces erreurs, les Singletons peuvent toujours être un PITA, mais il est prêt à voir que beaucoup des pires problèmes sont considérablement atténués. Imaginez un Java Singleton, qui est explicitement défini comme une fois par chargeur de classe (ce qui signifie qu'il a besoin d'une politique de sécurité des threads), avec des méthodes de création et de destruction définies et un cycle de vie qui dicte quand et comment ils doivent être invoqués, et dont la méthode "instance" a protection du package afin qu'il soit généralement accessible via 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 sur la façon de faire des singletons. Nous enseignons de mauvais exemples, laissons les programmeurs s'en servir pendant un certain temps, puis leur disons que c'est un mauvais modèle de conception.
la source
Voir Wikipedia Singleton_pattern
Références (uniquement les références pertinentes de l'article)
la source
Ce n'est pas que les singletons eux-mêmes sont mauvais, mais le modèle de conception du GoF l'est. Le seul argument vraiment valable est que le modèle de conception du GoF ne se prête pas aux tests, surtout si les tests sont exécutés en parallèle.
L'utilisation d'une seule instance d'une classe est une construction valide tant que vous appliquez les moyens suivants dans le code:
Assurez-vous que la classe qui sera utilisée comme singleton implémente une interface. Cela permet aux stubs ou aux mocks d'être implémentés en utilisant la même interface
Assurez-vous que le Singleton est thread-safe. C'est une évidence.
Le singleton doit être de nature simple et pas trop compliqué.
Pendant l'exécution de votre application, où des singletons doivent être passés à un objet donné, utilisez une fabrique de classes qui construit cet objet et demandez à la fabrique de classes de passer l'instance singleton à la classe qui en a besoin.
Pendant les tests et pour garantir un comportement déterministe, créez la classe singleton en tant qu'instance distincte soit la classe réelle elle-même, soit un stub / mock qui implémente son comportement et le transmettez tel quel à la classe qui le requiert. N'utilisez pas le facteur de classe qui crée cet objet sous test qui a besoin du singleton pendant le test car il en transmettra l'instance globale unique, ce qui va à l'encontre du but.
Nous avons utilisé des singletons dans nos solutions avec beaucoup de succès qui peuvent être testés, garantissant un comportement déterministe dans des flux de tests parallèles.
la source
Je voudrais aborder les 4 points de la réponse acceptée, j'espère que quelqu'un pourra expliquer pourquoi je me trompe.
Pourquoi masquer les dépendances dans votre code est-il mauvais? Il existe déjà des dizaines de dépendances cachées (appels d'exécution C, appels d'API OS, appels de fonction globale) et les dépendances singleton sont faciles à trouver (recherchez par exemple ()).
"Faire quelque chose de global pour éviter de le faire passer est une odeur de code." Pourquoi ne passe-t-on pas quelque chose pour éviter d'en faire un singleton 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 bien?
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 de savoir pourquoi l'ajout de cette "responsabilité" spécifique à une question de classe?
Pourquoi le passage d'un objet à une classe le rend-il plus étroitement couplé que l'utilisation de cet objet comme singleton à partir de la classe?
Pourquoi cela change-t-il la durée de l'État? Les singletons peuvent être créés ou détruits manuellement, le contrôle est donc toujours là et vous pouvez rendre la durée de vie identique à celle d'un objet non singleton.
Concernant les tests unitaires:
la source
Vince Huston a ces critères, qui me semblent raisonnables:
la source
Les singletons sont mauvais d'un point de vue puriste.
D'un point de vue pratique, un singleton est un compromis entre temps et complexité .
Si vous savez que votre application ne changera pas tant que ça, c'est tout à fait acceptable. Sachez simplement que vous devrez peut-être refaçonner les choses si vos besoins changent de manière inattendue (ce qui est assez bien dans la plupart des cas).
Les singletons compliquent parfois les tests unitaires .
la source
Il n'y a rien de fondamentalement mauvais avec le modèle, en supposant qu'il soit utilisé pour un aspect de votre 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.
la source
Je ne vais pas commenter l'argument du bien / du mal, mais je ne les ai pas utilisés depuis l' arrivée du printemps . L'utilisation de l'injection de dépendances a pratiquement supprimé mes exigences pour les singleton, les servicelocators 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).
la source
Singleton est un modèle et peut être utilisé ou abusé comme tout 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 faire). Le plus gros délinquant utilise un singleton comme fausse variable globale.
la source
Lorsque vous écrivez du code à l'aide de singletons, par exemple, un enregistreur ou une connexion à une base de données, et que vous découvrez ensuite que vous avez besoin de plusieurs journaux ou de plusieurs bases de données, vous rencontrez des problèmes.
Les singletons font qu'il est très difficile de passer d'eux à des objets normaux.
De plus, 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 d'une fonction à l'autre. Cela peut être simplifié si vous les enveloppez tous dans un objet d'assistance, comme ceci:
la source
Le problème avec les singletons est la question de la portée accrue et donc couplage . Il est indéniable qu'il existe certaines situations où vous avez besoin d'accéder à une seule instance, et cela peut être accompli d'autres façons.
Je préfère maintenant concevoir autour d'une inversion de contrôle conteneur (IoC) et permettre aux durées de vie d'être contrôlées par le conteneur. Cela vous donne l'avantage des classes qui dépendent de l'instance pour ignorer le fait qu'il existe une seule instance. La durée de vie du singleton peut être modifiée à l'avenir. Un tel exemple que j'ai rencontré récemment était un ajustement facile de simple thread à multi-thread.
FWIW, s'il s'agit d'un PIA lorsque vous essayez de le tester à l'unité, il passe à PIA lorsque vous essayez de le déboguer, de le corriger ou de l'améliorer.
la source
Article récent sur ce sujet par Chris Reath à Coding Without Comments .
Remarque: le codage sans commentaires n'est plus valide. Cependant, l'article auquel 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
la source
Les singletons ne sont PAS mauvais. Ce n'est mauvais que lorsque vous créez quelque chose d'unique au niveau mondial qui ne l'est pas au niveau mondial.
Cependant, il existe des "services de portée d'application" (pensez à un système de messagerie qui fait interagir les composants) - ce CALLS pour un singleton, une classe "MessageQueue" - qui a une méthode "SendMessage (...)".
Vous pouvez ensuite effectuer les opérations suivantes de partout:
MessageQueue.Current.SendMessage (nouveau MailArrivedMessage (...));
Et, bien sûr, faites:
MessageQueue.Current.RegisterReceiver (this);
dans les classes qui implémentent IMessageReceiver.
la source
Trop de gens placent des objets qui ne sont pas thread-safe dans un motif singleton. J'ai vu des exemples d'un DataContext ( LINQ to SQL ) fait dans un modèle singleton, malgré le fait que le DataContext n'est pas sûr pour les threads et est purement un objet unité de travail.
la source
Voici encore une chose au sujet des singletons que personne n'a encore dit.
Dans la plupart des cas, "singletonity" est un détail d'implémentation pour une classe plutôt que la caractéristique de son interface. L'inversion du conteneur de contrôle peut masquer cette caractéristique aux utilisateurs de classe; il vous suffit de marquer votre classe comme un singleton (avec
@Singleton
annotation en Java par exemple) et c'est tout; L'IoCC fera le reste. Vous n'avez pas besoin de fournir un accès global à votre instance singleton car l'accès est déjà géré par IoCC. Il n'y a donc rien de mal avec les singletons IoC.Les singletons GoF à l'opposé des singletons IoC sont censés exposer la "singletonité" dans l'interface via la méthode getInstance (), et de sorte qu'ils souffrent de tout ce qui précède.
la source
Les singletons ne sont pas mauvais, si vous les utilisez correctement et de façon minimale . Il existe de nombreux autres bons modèles de conception qui remplacent les besoins de singleton à un moment donné (et donnent également les meilleurs résultats). Mais certains programmeurs ne connaissent pas ces bons modèles et utilisent le singleton pour tous les cas, ce qui le rend mauvais pour eux.
la source
Premièrement, une classe et ses collaborateurs devraient d'abord réaliser leur objectif plutôt que de se concentrer sur les personnes à charge. La gestion du cycle de vie (lorsque des instances sont créées et hors de portée) ne doit pas faire partie de la responsabilité des classes. La meilleure pratique acceptée pour cela consiste à créer ou à configurer un nouveau composant pour gérer les dépendances à l'aide de l'injection de dépendance.
Souvent, les logiciels deviennent plus compliqués, il est logique d'avoir plusieurs instances indépendantes de la classe Singleton avec un état différent. Commettre du code pour simplement saisir le singleton est incorrect dans de tels cas. En utilisant
Singleton.getInstance()
peut être correcte pour les petits systèmes simples, mais cela ne fonctionne pas / échelle quand on peut avoir 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 utilisation ou de la façon dont elle est utilisée pour configurer les dépendants. Pour une solution rapide et désagréable, cela n'a pas d'importance - un simple codage dur dit que les chemins de fichiers n'ont pas d'importance mais pour les applications plus grandes, ces dépendances doivent être factorisées et gérées de manière plus appropriée à l'aide de DI.
Les problèmes que singleton causent lors des tests sont un symptôme de leur cas / environnement à usage unique codé en dur. La suite de tests et les nombreux tests sont chacun individuels et séparent quelque chose qui n'est pas compatible avec le codage en dur d'un singleton.
la source
Comme ce sont essentiellement des variables globales orientées objet, vous pouvez généralement concevoir vos classes de manière à ne pas en avoir besoin.
la source