Question Quel est le problème des singletons? [fermé]


le motif singleton est un membre entièrement libéré de GoFde livre de modèles, mais il semble récemment plutôt orphelins par le monde du développeur. J'utilise encore pas mal de singletons, surtout pour classes d'usine, et même si vous devez faire attention aux problèmes de multithreading (comme n'importe quelle classe), je ne vois pas pourquoi ils sont si terribles.

Stack Overflow semble surtout supposer que tout le monde est d'accord que Singletons sont mauvais. Pourquoi?

S'il vous plaît soutenir vos réponses avec "faits, références ou expertise spécifique"


1737


origine


Réponses:


Paraphrasé de Brian Button:

  1. Ils sont généralement utilisés comme une instance mondiale, pourquoi est-ce si mauvais? Parce que vous cachez 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 circuler 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 cycle de vie.

  3. Ils provoquent intrinsèquement le code à être étroitement accouplé. Cela rend leur mise à l'épreuve plutôt difficile dans de nombreux cas.

  4. Ils portent l'état autour de la durée de vie de l'application. Un autre hit à tester puisque vous pouvez vous retrouver avec une situation où des tests doivent être commandés, ce qui est un gros non non pour les tests unitaires. Pourquoi? Parce que chaque test unitaire devrait être indépendant de l'autre.


1148



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 instance unique,

tu as besoin d'un singleton.

Il n'y a pas beaucoup d'exemples. Un fichier journal est le gros. Vous ne voulez pas abandonner un seul fichier journal. Vous voulez vider, synchroniser et fermer correctement. Ceci est un exemple d'une seule ressource partagée 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 libéré du GoF Modèles de conception livre.

Quand vous pensez que vous avez besoin d'un global, vous faites probablement une erreur de conception terrible.


399



Certains snobs de codage les regardent comme simplement glorifiés au niveau mondial. De la même manière que beaucoup de gens détestent le aller à déclaration il y a d'autres qui détestent l'idée de jamais utiliser un global. J'ai vu plusieurs développeurs faire des choses extraordinaires pour éviter global parce qu'ils considéraient en utiliser un comme un aveu d'échec. Etrange mais vrai.

En pratique, le Singleton modèle est juste 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 ainsi l'utiliser. Mais en l'utilisant juste pour que vous puissiez vous vanter d'utiliser un design pattern est aussi stupide que de refuser de l'utiliser parce que c'est juste un global.


306



Misko Hevery, de Google, a quelques 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épendances et démarrer ou tester une application. C'est un exemple assez abusif d'abus, mais le point qu'il fait valoir est toujours valable:

Les singletons ne sont rien de plus qu'un état global. L'état global permet à vos objets d'obtenir secrètement des choses qui ne sont pas déclarées dans leurs API, et, par conséquent, les singletons font de vos API des menteurs pathologiques.

Où sont passés tous les Singletons? fait le point que l'injection de dépendance a rendu facile d'obtenir des instances pour les constructeurs qui en ont besoin, ce qui allège le besoin sous-jacent derrière les mauvais singletons mondiaux décriés dans le premier article.


200



Je pense que la confusion est causée par le fait que les gens ne connaissent pas l'application réelle du modèle de Singleton. Je ne peux pas insister assez sur cela. Singleton est ne pas un motif pour envelopper les globales. Le motif Singleton ne doit être utilisé que pour garantir que 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 globals. C'est à cause de cette confusion que Singleton est méprisé. S'il vous plaît, ne confondez pas Singletons et globals. Si elle est utilisée pour le but pour lequel elle a été conçue, vous obtiendrez des avantages extrêmes du modèle Singleton.


103



Une chose plutôt mauvaise à propos des singletons est que vous ne pouvez pas les étendre très facilement. Vous devez essentiellement construire une sorte de motif décorateur ou une telle chose si vous voulez changer leur comportement. En outre, si un jour vous voulez avoir plusieurs façons de faire une chose, cela peut être plutôt douloureux de changer, selon la façon dont vous présentez votre code.

Une chose à noter, si vous utilisez des singletons, essayez de les transmettre à ceux qui en ont besoin plutôt que de les avoir directement accès ... Sinon, si vous choisissez d'avoir plusieurs façons de faire ce que Singleton fait, ce sera plutôt difficile à changer car chaque classe incorpore une dépendance si elle accède directement au singleton.

Donc en gros:

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

plutôt que:

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

Je crois que ce genre 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 si ... Pensez-y et considérez si son utilisation dans la situation donnée est inappropriée ou non ... Les règles sont faites pour être brisées d'habitude, et modèles ne devrait pas être appliqué willy nilly sans pensée.


71



Le modèle singleton n'est pas un problème en soi. Le problème est que le modèle est souvent utilisé par les développeurs de logiciels avec des outils orientés objet sans avoir une bonne compréhension des concepts OO. Lorsque les singletons sont introduits dans ce contexte, ils tendent à devenir des classes ingérables qui contiennent des méthodes auxiliaires 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. Inversion de 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 à des tests unitaires.

Dans un déchets ramassés environnement singletons peut rapidement devenir un problème en ce qui concerne la gestion de la mémoire.

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


65



Un singleton est implémenté en utilisant 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 é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 l'utilisation de inversion de contrôle modèle.


52



Singletons sont également mauvais quand il s'agit de regroupement. Parce que 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 ne sont pas en conflit les uns avec les autres, 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...
        }
    }
}

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 celle-ci SingletonDao. Votre environnement de production ressemble maintenant à ceci: Single Singleton

Tout va bien jusqu'à présent.

Maintenant, pensez à configurer plusieurs instances de votre application Web dans un cluster. Maintenant, vous avez soudainement quelque chose comme ça:

Many singletons

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: avoir beaucoup d'objets. Cela est particulièrement grave si vous souhaitez, comme indiqué dans cet exemple, 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 sur le fait qu'il existe exactement une instance d'un singleton dans votre application, en particulier lorsqu'il s'agit de clustering.


42