Nommez les considérations de conception pour décider entre l'utilisation d'un singleton et d'une classe statique. En faisant cela, vous êtes en quelque sorte obligé de contraster les deux, donc tous les contrastes que vous pouvez trouver sont également utiles pour montrer votre processus de pensée! De plus, chaque intervieweur aime voir des exemples illustratifs. :)
design-patterns
cdleary
la source
la source
Réponses:
la source
Que diriez-vous "d'éviter les deux"? Singletons et classes statiques:
Au lieu de cela, examinez l' injection de dépendances et l' inversion des bibliothèques de conteneurs de contrôle . Plusieurs bibliothèques IoC se chargeront de la gestion de la durée de vie pour vous.
(Comme toujours, il existe des exceptions, telles que les classes mathématiques statiques et les méthodes d'extension C #.)
la source
Hide Dependencies
Little sideinfo sur ce point: Vous pouvez implémenter le modèle Inversion of Control par exemple en utilisant Ninject . Cela vous permet de n'utiliser qu'une seule instance d'un type en la liant à aSingletonScope
, ce qui signifie qu'elle injectera toujours la même instance, mais que la classe ne sera pas singleton.Je dirais que la seule différence est la syntaxe: MySingleton.Current.Whatever () vs MySingleton.Whatever (). L'État, comme David l'a mentionné, est finalement «statique» dans les deux cas.
EDIT: La brigade d'enterrement est venue de Digg ... de toute façon, j'ai pensé à un cas qui nécessiterait un singleton. Les classes statiques ne peuvent pas hériter d'une classe de base ni implémenter une interface (du moins en .Net, elles ne le peuvent pas). Donc, si vous avez besoin de cette fonctionnalité, vous devez utiliser un singleton.
la source
Une de mes discussions préférées sur ce problème est ici (site d'origine en panne, maintenant lié à Internet Archive Wayback Machine .)
Pour résumer les avantages de flexibilité d'un Singleton:
la source
Une classe statique avec une charge de variables statiques est un peu un hack.
Un singleton avec une instance réelle est mieux.
L'état est UNIQUEMENT dans l'instance.
Ainsi, le singleton peut être modifié plus tard pour faire du pooling, des instances locales de thread, etc.
Il est possible de faire quelque chose de similaire avec une classe statique, mais il y aura une surcharge par appel dans la distribution indirecte.
Vous pouvez obtenir l'instance et la transmettre à une fonction en tant qu'argument. Cela permet au code d'être dirigé vers le «bon» singleton. Nous savons que vous n'en aurez besoin que d'un seul ... jusqu'à ce que vous n'en ayez pas besoin.
Le gros avantage est que les singletons avec état peuvent être rendus sûrs pour les threads, alors qu'une classe statique ne le peut pas, à moins que vous ne le modifiiez pour être un singleton secret.
la source
Pensez à un singleton comme un service. C'est un objet qui fournit un ensemble spécifique de fonctionnalités. Par exemple
La fabrique d'objets est un objet qui effectue un service spécifique.
En revanche, une classe pleine de méthodes statiques est une collection d'actions que vous voudrez peut-être effectuer, organisées dans un groupe lié (la classe). Par exemple
L'exemple StringUtils ici est une collection de fonctionnalités qui peuvent être appliquées n'importe où. L'objet de fabrique singleton est un type d'objet spécifique avec une responsabilité claire qui peut être créée et transmise si nécessaire.
la source
Les classes statiques sont instanciées au moment de l'exécution. Cela peut prendre du temps. Les singletons ne peuvent être instanciés qu'en cas de besoin.
la source
Les singletons ne doivent pas être utilisés de la même manière que les classes statiques. En essence,
est essentiellement le même que
En fait, vous devriez traiter le singleton comme un simple objet . Si un service nécessite une instance du type singleton, transmettez cette instance au constructeur:
Le service ne doit pas savoir que l'objet est un singleton et doit traiter l'objet comme un simple objet.
L'objet peut certainement être implémenté, en tant que détail d'implémentation et en tant qu'aspect de la configuration globale, en tant que singleton si cela facilite les choses. Mais les choses qui utilisent l'objet ne devraient pas avoir à savoir si l'objet est un singleton ou non.
la source
Si par "classe statique" vous entendez une classe qui n'a que des variables statiques, elles peuvent en fait maintenir l'état. Je crois comprendre que la seule différence serait la façon dont vous accédez à cette chose. Par exemple:
contre
Les composants internes de MySingleton seront évidemment différents entre eux mais, mis à part les problèmes de sécurité des threads, ils fonctionneront tous les deux de la même manière en ce qui concerne le code client.
la source
Le modèle Singleton est généralement utilisé pour traiter des données statiques ou indépendantes de l'instance où plusieurs threads peuvent accéder aux données en même temps. Un exemple peut être les codes d'état.
la source
Les singletons ne doivent jamais être utilisés (sauf si vous considérez une classe sans état mutable comme un singleton). Les "classes statiques" ne devraient avoir aucun état mutable, à part peut-être des caches thread-safe et autres.
Presque tous les exemples de singleton montrent comment ne pas le faire.
la source
Si un singleton est quelque chose dont vous pouvez vous débarrasser, pour nettoyer après lui, vous pouvez le considérer quand il s'agit d'une ressource limitée (c'est-à-dire seulement 1) dont vous n'avez pas besoin tout le temps, et que vous avez une sorte de mémoire ou coût des ressources lorsqu'il est alloué.
Le code de nettoyage semble plus naturel lorsque vous avez un singleton, par opposition à une classe statique contenant des champs d'état statiques.
Le code, cependant, sera un peu le même dans les deux cas, donc si vous avez des raisons plus spécifiques de demander, vous devriez peut-être élaborer.
la source
Les deux peuvent être assez similaires, mais rappelez-vous que le vrai Singleton doit lui-même être instancié (accordé, une fois) puis servi. Une classe de base de données PHP qui renvoie une instance de
mysqli
n'est pas vraiment un Singleton (comme certains l'appellent), car elle renvoie une instance d'une autre classe, pas une instance de la classe qui a l'instance en tant que membre statique.Donc, si vous écrivez une nouvelle classe dont vous prévoyez de n'autoriser qu'une seule instance dans votre code, vous pouvez aussi bien l'écrire en tant que Singleton. Considérez cela comme l'écriture d'une classe ordinaire et l'ajout à celle-ci pour faciliter l'exigence d'instanciation unique. Si vous utilisez la classe de quelqu'un d'autre que vous ne pouvez pas modifier (comme
mysqli
), vous devriez utiliser une classe statique (même si vous ne parvenez pas à préfixer sa définition avec le mot-clé).la source
Les singletons sont plus flexibles, ce qui peut être utile dans les cas où vous souhaitez que la méthode Instance renvoie différentes sous-classes concrètes du type Singleton en fonction d'un contexte.
la source
Les classes statiques ne peuvent pas être transmises comme arguments; les instances d'un singleton peuvent être. Comme mentionné dans d'autres réponses, surveillez les problèmes de thread avec les classes statiques.
rp
la source
Un singleton peut avoir un constructeur et un destructeur. En fonction de votre langage, le constructeur peut être appelé automatiquement la première fois que votre singleton est utilisé, ou jamais si votre singleton n'est pas du tout utilisé. Une classe statique n'aurait pas une telle initialisation automatique.
Une fois qu'une référence à un objet singleton est obtenue, elle peut être utilisée comme n'importe quel autre objet. Le code client n'a même pas besoin de savoir qu'il utilise un singleton si une référence au singleton est stockée plus tôt:
Cela facilite évidemment les choses lorsque vous choisissez d'abandonner le modèle Singleton au profit d'un modèle réel, comme IoC.
la source
Utilisez le modèle singleton lorsque vous avez besoin de calculer quelque chose au moment de l'exécution que vous calculeriez au moment de la compilation si vous le pouviez, comme des tables de recherche.
la source
Je pense qu'un endroit où Singleton aura plus de sens que la classe statique est lorsque vous devez construire un pool de ressources coûteuses (comme des connexions de base de données). Vous ne seriez pas intéressé par la création du pool si personne ne les utilise (une classe statique signifie que vous effectuez le travail coûteux lorsque la classe est chargée).
la source
Un singleton est également une bonne idée si vous souhaitez forcer une mise en cache efficace des données. par exemple, j'ai une classe qui recherche des définitions dans un document xml. Puisque l'analyse du document peut prendre un certain temps, j'ai mis en place un cache de définitions (j'utilise SoftReferences pour éviter outOfmemeoryErrors). Si la définition souhaitée n'est pas dans le cache, je fais l'analyse XML coûteuse. Sinon, je renvoie une copie du cache. Étant donné que le fait d'avoir plusieurs caches signifierait que je pourrais encore devoir charger la même définition plusieurs fois, j'ai besoin d'un cache statique. J'ai choisi d'implémenter cette classe en tant que singleton afin de pouvoir écrire la classe en utilisant uniquement des membres de données normaux (non statiques). Cela me permet de créer encore une istantiation de la classe si j'en ai besoin pour une raison quelconque (sérialisation, test unitaire, etc.)
la source
Singleton est comme un service, comme déjà mentionné. Le pro est sa flexibilité. Statique, eh bien, vous avez besoin de certaines parties statiques pour implémenter Singleton.
Singleton a du code pour s'occuper de l'instanciation de l'objet réel, ce qui peut être d'une grande aide si vous rencontrez des problèmes de course. Dans une solution statique, vous devrez peut-être gérer des problèmes de course à plusieurs emplacements de code.
Cependant, comme Singleton peut être construit avec des variables statiques, vous pourrez peut-être le comparer avec 'goto'. Cela peut être très utile pour construire d'autres structures, mais vous devez vraiment savoir comment l'utiliser et ne pas en abuser. Par conséquent, la recommandation générale est de s'en tenir à Singleton et d'utiliser statique si nécessaire.
Vérifiez également l'autre article: Pourquoi choisir une classe statique plutôt qu'une implémentation singleton?
la source
référer ceci
sommaire:
une. Une règle de base simple que vous pouvez suivre est que si elle n'a pas besoin de maintenir l'état, vous pouvez utiliser une classe statique, sinon vous devriez utiliser un Singleton.
b. utilisez un Singleton s'il s'agit d'un objet particulièrement «lourd». Si votre objet est volumineux et occupe une quantité raisonnable de mémoire, beaucoup d'appels n / w (pool de connexions) ..etc. Pour vous assurer qu'il ne sera pas instancié plusieurs fois. Une classe Singleton aidera à éviter qu'un tel cas ne se produise
la source
Lorsque la classe unique a besoin d'un état. Les singletons conservent un état global, contrairement aux classes statiques.
Par exemple, créer une aide autour d'une classe de registre: si vous avez une ruche modifiable (HKey Current User vs HKEY Local Machine), vous pouvez aller:
Désormais, tout autre appel à ce singleton fonctionnera sur la ruche de la machine locale. Sinon, en utilisant une classe statique, vous devrez spécifier que la machine locale ruche tous les éléments, ou avoir une méthode comme
ReadSubkeyFromLocalMachine
.la source