Question

Quand ne devriez-vous PAS utiliser une classe singleton bien que cela puisse être très tentant? Ce serait très bien si nous avions une liste des cas les plus courants de «singletonitis» que nous devrions prendre soin d'éviter.

Était-ce utile?

La solution

N'utilisez pas un singleton pour quelque chose qui pourrait évoluer en une ressource multipliable.

Cela semble probablement idiot, mais si vous déclarez quelque chose comme un singleton, vous déclarez très clairement que c'est absolument unique. Vous construisez de plus en plus de code. Et lorsque vous découvrez alors, après des milliers de lignes de code, que ce n'est pas du tout un singleton, vous avez une énorme quantité de travail devant vous car tous les autres objets s’attendent à "& the;" objet sacré de la classe WizBang d'être un singleton.

Exemple typique: "Il n'y a qu'une seule connexion de base de données à cette application, il s'agit donc d'un singleton." - Mauvaise idée. Vous voudrez peut-être avoir plusieurs connexions dans le futur. Mieux créer un pool de connexions de base de données et le remplir avec une seule instance. Agit comme un singleton, mais tous les autres codes auront un code développable pour accéder au pool.

MODIFIER: Je comprends qu'en théorie, vous pouvez étendre un singleton en plusieurs objets. Cependant, il n’existe pas de véritable cycle de vie (comme la mise en commun / le regroupement), ce qui signifie qu’il n’existe pas de véritable propriété des objets distribués, c’est-à-dire que le multi-singleton, à présent, devrait être apatride pour pouvoir être utilisé simultanément par différentes méthodes et fonctions. / p>

Autres conseils

Eh bien, les singletons, pour la plupart, ne font que rendre les choses statiques de toute façon. Donc, soit vous êtes en train de rendre les données globales, et nous savons tous que les variables globales sont mauvaises ou vous écrivez des méthodes statiques et ce n'est pas très OO maintenant, n'est-ce pas?

Voici est un discours plus détaillé sur la raison pour laquelle les singletons sont mauvais, par Steve Yegge. Fondamentalement, vous ne devriez pas utiliser des singletons dans presque tous les cas, vous ne pouvez pas savoir que cela ne sera jamais nécessaire à plus d’un endroit.

Je sais que beaucoup ont répondu "quand vous avez plus d'un", etc.

.

Puisque l'affiche originale voulait une liste de cas dans lesquels vous ne devriez pas utiliser Singletons (plutôt que la raison principale), je vais vous donner un commentaire:

Chaque fois que vous l'utilisez parce que vous n'êtes pas autorisé à utiliser un global!

Nombre de fois où un ingénieur junior a utilisé un Singleton parce qu'ils savaient que je n'acceptais pas les globals dans les évaluations de code. Ils semblent souvent choqués lorsque je souligne que tout ce qu'ils ont fait, c'est remplacer un modèle global par un modèle Singleton et qu'ils n'en ont toujours qu'un!

Je suis coupable d’un gros coup il ya quelques années (heureusement, j’ai appris mon lession depuis.).

Ce qui s’est passé, c’est que j’ai intégré un projet d’application de bureau converti au format .Net à partir de VB6 et que c’était un vrai désastre. Des choses comme des fonctions (imprimées) de 40 pages et aucune structure de classe réelle. J'ai construit une classe pour encapsuler l'accès à la base de données. Pas encore un vrai niveau de données, juste une classe de base qu'un vrai niveau de données pourrait utiliser. Quelque part, j'ai eu la brillante idée de faire de cette classe un singleton. Cela a fonctionné pendant environ un an, puis nous avons également dû créer une interface Web pour l'application. Le singleton a fini par être un énorme goulot d'étranglement pour la base de données, car tous les utilisateurs Web devaient partager la même connexion. Encore une fois ... la leçon apprise.

Rétrospectivement, c’était probablement le bon choix pour un court moment, car il obligeait les autres développeurs à faire preuve de plus de discipline dans leur utilisation et à les sensibiliser à des problèmes de portée qui n’étaient pas un problème auparavant dans le monde VB6. Mais j’aurais dû le remplacer au bout de quelques semaines avant que nous en soyons trop entourés.

Voici un délire de mon ami Alex Miller ... Il n’énumère pas exactement "quand vous NE devez PAS utiliser un singleton". mais c’est un article complet, excellent et soutient qu’il ne faut utiliser un singleton que dans de rares cas, voire jamais.

Les singletons sont pratiquement toujours une mauvaise idée et sont généralement inutiles / redondants car ils ne sont qu'une simplification très limitée d'un modèle décent.

Recherchez le fonctionnement de l'injection de dépendance. Il résout les mêmes problèmes, mais de manière beaucoup plus utile. En fait, il s’applique à de nombreuses autres parties de votre conception.

Bien que vous puissiez trouver des bibliothèques de DI sur le marché, vous pouvez également en créer une de base vous-même, c'est assez facile.

J'essaie de n'avoir qu'un seul singleton - une inversion d'objet de contrôle / service de localisation.

IService service = IoC.GetImplementationOf<IService>();

L’un des éléments qui en fait un cauchemar est si elle contient un état global modifiable . J'ai travaillé sur un projet dans lequel des singletons étaient utilisés partout pour des problèmes qui auraient dû être résolus d'une manière complètement différente (stratégies de passe, etc.). Le "de-singletonification". était dans certains cas une réécriture majeure de certaines parties du système. Je dirais que dans la plus grande partie des cas où les gens utilisent un Singleton, c'est tout simplement faux parce que ça a l'air sympa en premier lieu, mais ça devient un problème surtout dans les tests.

Lorsque plusieurs applications s'exécutent sur la même machine virtuelle.

Un singleton est un singleton sur l’ensemble de la JVM, pas seulement une seule application. Même si plusieurs threads ou applications semblent créer un nouvel objet singleton, ils utilisent tous le même objet s’ils s’exécutent dans la même machine virtuelle.

Parfois, vous supposez qu'il n'y en aura qu'une, puis vous vous trompez.

Exemple, une classe de base de données. Vous supposez que vous ne vous connecterez jamais qu'à la base de données de votre application.

// Its our database! We'll never need another
class Database
{
};

Mais attendez! Votre patron dit, connectez-vous à une base de données d'autres gars. Supposons que vous souhaitiez ajouter phpbb au site web et que vous souhaitiez utiliser sa base de données pour intégrer certaines de ses fonctionnalités. Devrions-nous créer un nouveau singleton ou une autre instance de base de données? La plupart des gens s'accordent pour dire qu'une nouvelle instance de la même classe est préférable, il n'y a pas de duplication de code.

Vous préférez avoir

Database ourDb;
Database otherDb;

que la base de données copier-coller et faire:

// Copy-pasted from our home-grown database.
class OtherGuysDatabase
{
};

La pente glissante ici est que vous pouvez cesser de penser à créer de nouvelles instances de classes et commencer à penser qu’il est correct d’avoir un type par instance.

Dans le cas d'une connexion (par exemple), il est logique que vous ne vouliez pas faire de la connexion elle-même un singleton, vous devrez peut-être quatre connexions ou vous devrez peut-être détruire et recréer la connexion fois.

Mais pourquoi n'accédez-vous pas à toutes vos connexions via une interface unique (gestionnaire de connexions, par exemple)?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top