Duplicaté possible: strong>
sur les modèles de conception: quand utiliser le singleton? p> blockQuote>Cette question ne concerne pas si les singletons sont "considérés comme nocifs" en général. Je veux juste savoir, de votre expérience, quelles sont des situations fortes> spécifiques fortes> dans lesquelles singletons semblent bien fonctionner. P>
edit: strong> S'il vous plaît, si vous voulez discuter de la pertinence et / ou de la perturbation des singletons en général strong>, il existe déjà des questions supplémentaires: 137975 , 11831 a> p> oups! Je viens de découvrir que ma question avait déjà été posée ici: sur conception Modèles: quand utiliser le singleton? P>
12 Réponses :
Il y a un seul appareil / matériel connecté au système et un point central de contrôle est nécessaire pour l'utiliser correctement. P>
J'ai vu une "singletonisation prématurée" dans des systèmes intégrés où le pilote d'un port de communication ne prendrait que supporter une instance. Plus tard, lorsque davantage de ports de communes sont devenus disponibles, le pilote devait être révisé pour soutenir plusieurs instances. Certaines parties du code d'application à l'aide du pilote de Port Comm devaient également une réécriture. Je me demande, quel appareil serait toujours vraiment unique et n'a jamais eu de nombreuses instances?
Je dirais également de ne pas utiliser un singleton pour le matériel. Sinon, vous ne pouvez pas tester votre code séparément du matériel. Mieux pour créer une interface. Je peux voir un singleton étant utile si vous devez écrire sur le matériel de nombreux endroits différents de votre code, mais il me semble que ce serait une mauvaise conception.
Je viens de travailler vraiment difficile de me débarrasser des singletons dans le projet actuel que je travaille. Ils ont une odeur, mais sont parfois très difficiles à éviter. P>
Ma situation était que j'avais une API qui a construit des objets Singleton pour la gestion des fonctions de gestion telles que la sécurité, la configuration, etc. L'API a utilisé l'entité deframework et également tiré dans les plugins (à l'aide de MEF). Étant donné que la construction de ces classes n'a pas toujours été effectuée par mon code (en particulier pour les entités EF), il n'a pas toujours été possible de les injecter dans des objets Biz élégamment. J'ai donc utilisé des singletons, qui peuvent être accessibles n'importe où dans un projet de soumission de projet. P>
Ils sont bons pour les articles que vous souhaitez considérer comme des ressources uniques. P>
À titre d'exemple dans Web Systems, vous pouvez utiliser uniquement une connexion de base de données unique pour chaque page servie - dans ce cas à l'aide du modèle Singleton aurait un sens. (Bien que vous ayez à coder avec les connaissances que l'objet d'accès à la base de données était un singleton, qui est moins idéal, mais acceptable si clairement documenté, etc.) p>
Nous les utilisons essentiellement pour deux choses: journalisation et configuration. Les deux supposent que l'application dispose d'une configuration centrale et d'un fichier journal central, pas toujours valable mais dans la plupart de notre code. Nous les utilisons également à l'occasion de certaines classes d'usine ou de classes de cache que nous voulons nous assurer que nous ne sommes pas dupliquant des métadonnées clés. P>
Lorsqu'une partie de votre programme a besoin d'un objet qui implémente une interface spécifique (polymorphisme-wise), mais vous ne voulez jamais plus d'une seule instance de cet objet. Sinon, les méthodes statiques feront. P>
Master Server prend des demandes de clients et transmet ces demandes d'un processus subordonné. Le processus subordonné peut utiliser un singleton pour communiquer avec le serveur principal. P>
Les bowvotes non motivés sont vraiment ennuyeux. Je décris un motif utilisé dans Postfix - Le serveur Master Postfix gère les chemins de connexion entre tous les autres exécutables du système. Si une sous-partie du système doit en parler un autre, elle doit utiliser le serveur maître pour savoir comment.
(Le Downvote n'est pas le mien) Vous pouvez exécuter plusieurs instances postfix sur une seule machine => Le maître n'est pas un singleton. De plus, ce ne serait pas une raison valable d'utiliser le motif de la mise en œuvre du subordonné, de l'OMI.
Le maître n'est pas un singleton, et je ne pense pas que je le décris comme tel. Chaque processus subordonné individuel a une connexion singleton avec le maître spécifique qui le contrôle. Cela n'a aucun sens pour un subordonné d'avoir plusieurs maîtres.
Ok, mais quel problème est résolu en utilisant le singleton DP dans le subordonné?
Je vois votre point ... Il existe des réponses possibles - le codage explicitement que le subordonné ne doit pas avoir plusieurs maîtres, ni appliquer la séparation de processus qui constitue une partie fondamentale du modèle de sécurité de Postfix (dans lequel certains des inconvénients des singletons (entravent les mêmes -Avoir le refactoring de code de l'espace) sont transformés en avantages, car il peut s'agir d'un objectif de conception d'appliquer la séparation des processus) - mais rien qui me semble vraiment convaincant.
J'essaie de ne pas compter sur Singleton, mais je préfère découpler de ne pas utiliser Singleton. Ainsi, j'utilise souvent Singleton couplé avec le modèle de prototype, qui permettent d'enregistrer les prototypes à la charge de la bibliothèque (construction d'objets globaux). P>
J'écris un serveur composé d'un certain nombre de bibliothèques. Il existe un certain nombre de bibliothèques "communes", puis une bibliothèque par service. Une bibliothèque "principale" est chargée du but de regarder le message reçu et d'appeler le bon service en fonction d'une clé ... Ceci utilise un simple Utiliser un singleton pour la carte permettez-moi d'avoir un code totalement découplé. Aucune bibliothèque ne dépend de ma bibliothèque de services, aucune ligne de code en dehors de ma bibliothèque de services est chargée d'enregistrer son service. En fait, il est telle que je puisse décider quels services sont incorporés simplement en modifiant ma commande "lien" à la compilation: si je ne lie pas avec une bibliothèque, son service n'est pas intégré. P>
Je trouve vraiment utile là-bas ... pour la configuration et je préfère utiliser le Monoptern: c'est-à-dire une classe d'apparence normale avec toutes les instances partageant les mêmes données (en appelant ainsi un vrai singleton). Donne une migration plus facile au cas où il est nécessaire, car les clients ne savent pas qu'ils utilisent un sous-couverture singleton. P> std :: map code>. P>.
journalisation. p> li>
Recherche de ressources de chaîne localisées par ex. Ces deux éléments ne sont pas des détails qui doivent être exposés dans l'interface publique de vos objets, il est donc logique d'utiliser un singleton ici. P> strings.get ("confirmer_delete") code>. p> li>
ul>
Je ne suis pas d'accord sur la seconde, du moins dans certaines applications. Et si vous voulez prendre en charge plusieurs langues à la fois?
Que voulez-vous dire à la fois? Strings.get ("FOO") récupérera la chaîne correcte d'un fichier de propriétés basé sur la langue actuelle. Changez la langue, redémarrez le programme et vous obtenez les nouvelles chaînes de la langue.
Si vous êtes un serveur de réseau, des connexions de manutention du monde entier, vous pouvez envoyer des chaînes à un client dans une langue et un autre client dans une autre langue.
Demander la chose de recherche de ressources ... Je vois actuellement une recherche singleton de chaînes localisées devenant un peu une douleur pour les tests unitaires (en Java). Une recherche unique tourne un test <0,1S dans un test 3S. Je peux voir cette montée. Alors que si la chose qui a fait la recherche a été injectée, je pourrais la simuler pour ne pas être un problème de performance.
Jouer à l'avocat du diable ici ... Que diriez-vous de Thestrings.get (langue, "confirmer_delete")?
En plus de la journalisation (comme la plupart des autres déjà mentionnées), j'ai utilisé des singletons pour inversion des conteneurs de contrôle (CIO). Les dépendances sont enregistrées une fois au début de la demande et on peut résoudre une dépendance à tout moment de l'application lors de l'application à l'aide de la méthode Singleton. P>
Est-ce similaire à ce qui est également connu sous le nom de modèle de localisateur de services, ou suis-je en train de mélanger mes modèles? :)
Développer mon commentaire ... P>
La question est mal libellée, les singletons semblent bien fonctionner em> dans de nombreuses situations. Il devrait être "Quelles sont certaines situations spécifiques dans lesquelles singletons n'exposent pas leurs propriétés négatives?" Brièvement, "quand les variables globales sont-elles bonnes"? P>
Une variable globale est une variable globale. P>
dès que vous utilisez p>
au lieu de singletons prolifère et tiens à dépendre de l'autre. singletons inhibe la testabilité. P>
La propriété mono-instance est semi-utile uniquement dans le code de production. Vous ne pouvez pas être incapable de tester la fonction Comme vous pouvez le deviner, ma réponse à quand les variables globales sont-elles bonnes? em> est "jamais". Qu'est-ce qui est votre em>? P>
void f ()
{
X * x = x :: getinstance ();
...
} code> p>
void f (x *) code>, votre commande pour le plat spaghetti a été acceptée. p> li>
sessionManager code> utilise
EventManager code> qui utilise
logManager code>. Quelqu'un veut que les fichiers journaux mentionnent le nom de l'utilisateur actuel. Le
logManager CODE> MAINTERER ajoute
SessionManager :: geInstance () -> getUser () -> getname (); code>, tout ce que c'est le loginManager code>, lequel utilise également
logManager code>, veut enregistrer une panne de connexion. p> li>
Void F () code> du tout et aurez probablement (peu de) tests uniquement pour le chemin heureux. P> Li>
ol>
"... Quand sont les variables globales bien?" I> Tu me demandes-tu? Jusqu'à présent, j'utiliserais des singletons (appelez-les globaux si vous le souhaitez) lorsque l'injection de dépendance serait une pita totale (un plus grand pita que les problèmes que les globaux de problèmes vous donnent des tests unitaires). Par exemple, je ne peux pas imaginer passer un objet de journalisation à chacune de mes classes.
-1 Pour ne pas répondre à ma question, désolé (je ne suis pas en désaccord avec votre point de vue, cependant). Je voulais savoir quelles sont les situations spécifiques b> où les singletons (appelez-les des globaux si vous le souhaitez) fonctionnent bien.
Je suis difficile à croire que chacune de vos classes i> a une entreprise enregistrant ses opérations. Sauf si vous utilisez la journalisation comme substitut à un débogueur. Quoi qu'il en soit, dans les cas où j'ai rencontré cette objection, la (perçue ou réelle) a été induite par un code spaghetti. Après refactoring, les singletons précédemment ont été adoptés si nécessaire, ce qui s'est avéré être une mesure très gérable.
J'étais très précis dans la réponse: jamais.
Votre réponse est allée contre l'esprit de ma question. Vous avez utilisé ma question comme une boîte à savon pour vos vues anti-singleton.
Retour à la truc de l'enregistreur, il y avait un cas où l'enregistreur était "abusé" à des fins de débogage et cela m'a bien servi. Le logiciel a été exécuté dans un environnement en temps réel difficile à dupliquer au bureau, il était donc important de se connecter aux détails de la minute dans une catégorie spéciale "de débogage". Si je devais tout recommencer, j'irais probablement que l'excise d'injecter l'enregistreur juste pour voir la quantité d'un pita C'est vraiment.
Ok, que dois-je faire différemment (sans changer le sens de la réponse) pour répondre à vos critères?
Red Logger: J'ai vu un enregistreur Singleton / Global utilisé dans une catégorie code> string code>. Je conviens que c'est très i> peu pratique de transmettre un enregistreur au constructeur de chaque instance d'une telle classe. Mais je pense aussi que cette classe n'a aucune entreprise dans la journalisation. Il y a une dichotomie imo: soit un objet doit être en train de se connecter, puis c'est une chose majeure (implique peu d'objets de ce type, près de la racine du graphique d'objet), ou c'est une petite créature, il y a un bazillion d'entre eux dans les couches inférieures, Mais ils sont trop petits et muettes pour vous connecter tout d'intéressant.
Hmmm .... Maintenant que j'y pense, il est bon de "remettre en question la question" et de penser en dehors de la boîte. Je l'ai fait moi-même et ce n'est pas juste pour moi de dire que vous ne pouvez pas le faire ici. Désolé d'être hypocrite. :-) Touchez simplement votre réponse et je vais annuler mon -1. En outre, votre réponse est un bon espace réservé pour d'autres personnes qui souhaitent également répondre "jamais".
Ok, fait et merci. Bien que je devrais mentionner que je ne vois pas ma réponse comme "remettre en question la question". Je dis plutôt que l'ensemble de situations spécifiques que vous posez sur est vide.
Je crois toujours que les singletons doivent être évités (au moins en Java). P>
Il y a deux choses différentes à considérer: le concept Le concept de singletons a beaucoup d'utilisations, de la journalisation, de la configuration, de ne pas mentionner lorsque le domaine que vous travaillez a des choses où il n'y a jamais qu'une seule instance et que vous souhaitez modéliser cela. C'est à dire. Une entreprise possède uniquement un bureau de traitement des dépenses unique et l'envoi de formulaires de dépenses à un bureau invalide est faux, le bureau est en réalité un singleton. Le concept d'un singleton a de nombreuses utilisations légitimes. P>
Cependant, c'est généralement le mécanisme qui provoque le problème. En Java, nous appliquons un objet ne peut pas être construit en déclarant le constructeur Si le concept de singletons peut être séparé des mauvais mécanismes, ils ne seraient pas aussi diaboliques. Un exemple, je peux penser à la lunette privé code>, le problème avec cela est également à fournir un point point d'accès global em> à l'instance à travers la classe de béton. Cela dépasse tout dans votre application sur cette classe de béton, qui ne peut pas être changée au moment de l'exécution ou se moqueur dans les tests de l'unité. C'est ce mécanisme considéré comme le mal - en particulier en termes de testabilité. P>
@singleton code> disponible à Guice. Dans le contexte de Guice, il garantit une instance, mais cela n'accueille pas cela avec le constructeur privé diabolique / point de mécanisme de point d'accès mondial. P>
générer une séquence de nombres aléatoires - le générateur aléatoire doit être unique, non instancié pour chaque utilisation. On pourrait vouloir mettre en œuvre cela comme un singleton de niveau de thread; Cependant, un singleton pour l'ensemble du processus est toujours approprié dans ce cas. p>
La question est mal formulée, les singletons semblent bien fonctionner dans de nombreuses situations. Il devrait être "quand les variables globales sont-elles bonnes"?
@just quelqu'un: Je vais laisser les gens interpréter "singleton" quelle que soit leur façon dont ils veulent. :)