2010-05-04 5 views
68

Je n'ai jamais trouvé de bonnes réponses à ces simples questions sur les classes utilitaires/utilitaires:Pourquoi utiliser un singleton au lieu de méthodes statiques?

Pourquoi est-ce que je créerais un singleton (sans état) au lieu d'utiliser des méthodes statiques?

Pourquoi une instance d'objet serait-elle nécessaire si un objet n'a pas d'état?

+0

duplication possible de http://stackoverflow.com/questions/720744/static-class-and-singleton –

+0

Ne pensez pas puisque nous parlons de 2 langages différents, donc la réponse peut varier, mais merci pour le lien, en java n'a jamais entendu le terme "monostate" –

Répondre

64

Un singleton est utilisé pour introduire une sorte d'état global dans une application. S'il est apatride, je ne vois pas aussi le point d'utiliser un singleton, à moins que

  • vous vous attendez à prolonger avec l'état dans un avenir prévisible ou
  • vous avez besoin d'une instance d'objet pour certains particulier technique raison (par exemple, pour l'instruction C# lock, bien que cela soit déjà farfelu) ou
  • vous avez besoin d'héritage, c'est-à-dire que vous voulez pouvoir facilement remplacer votre singleton par un autre en utilisant la même interface mais une implémentation différente. Par exemple, la méthode Toolkit.getDefaultToolkit() en Java renvoie un singleton dont le type exact dépend du système.
+23

Je vais aller avec +1, bien que les singletons à mon humble avis sont ** mal utilisés ** pour introduire des états globaux. Le but d'un singleton n'est pas de rendre un objet globalement disponible, mais de faire en sorte qu'un objet ne soit instancié qu'une seule fois. Les objets globaux sont un mal nécessaire. Sauf si vraiment nécessaire, il faut essayer de ne pas les utiliser, car ils conduisent généralement à un couplage élevé, avec SomeSingleton.getInstance(). SomeMethod() partout.:) – back2dos

+0

Cela peut être utile dans les jeux où vous ne voulez qu'une seule instance de rendu au lieu de plusieurs instances de rendu, ou avec une classe de tuyauterie réseau dans laquelle vous configurez un canal sécurisé avec une seule connexion à la fois. – Tschallacka

+2

"remplacer facilement votre singleton" partie est le point le plus important de mon point de vue. Le repos est assez proche de l'implémentation de classe statique. –

34

Je pourrais voir un cas pour un singleton sans état utilisé à la place d'une classe de méthodes statiques, à savoir pour Dependency Injection.

Si vous disposez d'une classe d'utilitaires auxiliaires que vous utilisez directement, cela crée une dépendance cachée; vous n'avez aucun contrôle sur qui peut l'utiliser, ou où. L'injection de cette même classe d'aide via une instance singleton sans état vous permet de contrôler où et comment elle est utilisée, et de la remplacer/se moquer d'elle/etc. quand vous en avez besoin. En faire une instance singleton vous assure simplement que vous n'allouez plus d'objets du type que nécessaire (puisque vous n'en avez besoin que d'un seul).

+1

* "vous n'avez aucun contrôle sur qui peut l'utiliser, ou où." * Pourquoi quelqu'un en aurait-il besoin? – hagrawal

+0

@hagrawal à des fins de test, vous devriez être en mesure de se moquer –

5

Dans la plupart des langages de programmation échapper à une grande partie du système de type. Alors qu'une classe, avec ses méthodes statiques et ses variables, est un objet, elle ne peut très souvent pas implémenter une interface ou étendre d'autres classes. Pour cette raison, il ne peut pas être utilisé de manière polymorphe, puisqu'il ne peut pas être le sous-type d'un autre type. Par exemple, si vous avez une interface IFooable, requise par plusieurs signatures de méthode d'autres classes, l'objet de classe StaticFoo ne peut pas être utilisé à la place de IFooable, alors que FooSingleton.getInstance() peut (en supposant que FooSingleton implémente IFooable).

Veuillez noter que, comme j'ai commenté la réponse de Heinzi, un singleton est un modèle pour contrôler l'instanciation. Il remplace new Class() par Class.getInstance(), ce qui donne à l'auteur de Class plus de contrôle sur les instances, qu'il peut utiliser pour empêcher la création d'instances inutiles. Le singleton est juste un cas très particulier du modèle d'usine et devrait être traité comme tel. L'utilisation commune en fait plutôt le cas particulier des registres globaux, qui finissent souvent mal, parce que les registres globaux ne devraient pas être utilisés simplement bon gré mal gré.

Si vous envisagez de fournir des fonctions d'assistance globales, les méthodes statiques fonctionneront parfaitement. La classe n'agira pas en tant que classe, mais plutôt en tant qu'espace de noms. Je suggère, vous conservez une haute cohésion, ou vous pourriez vous retrouver avec des problèmes de couplage les plus étranges.

greetz
back2dos

0

Singleton n'est pas apatride, elle détient l'état global.

Quelques raisons que je peux penser à utiliser Singleton sont:

  • Pour éviter des fuites de mémoire
  • Fournir le même état pour tous les modules dans une connexion de base de données application par exemple
+0

Je sais, mais en fait un singleton peut être plus ou moins être apatride ... S'il ne partage aucun attribut de classe ... –

11

En fait, je J'ai trouvé une autre réponse non mentionnée ici: les méthodes statiques sont plus difficiles à tester.

Il semble que la plupart des frameworks de test fonctionnent très bien pour les méthodes d'instance moqueuses, mais beaucoup d'entre eux ne gèrent pas correctement les méthodes statiques.

+2

Mais Powermock semble être en mesure de faites-le –

2

Il y a un compromis entre l'utilisation de laquelle. Singletons mai mai ou ne pas avoir d'état et ils se réfèrent à des objets. Si elles ne conservent pas l'état et ne sont utilisées que pour l'accès global, alors la statique est préférable car ces méthodes seront plus rapides. Mais si vous voulez utiliser des objets et des concepts de POO (polymorphisme d'héritage), singleton est préférable.

Considérons un exemple: java.lang.Runtime est une classe singleton dans Java. Cette classe autorise différentes implémentations pour chaque machine virtuelle Java. L'implémentation est unique par JVM. Si cette classe aurait été statique, nous ne pouvons pas passer des implémentations différentes basées sur JVM.

J'ai trouvé ce lien vraiment utile: http://javarevisited.blogspot.com/2013/03/difference-between-singleton-pattern-vs-static-class-java.html?

Espérons que ça aide !!

+0

Cette réponse est bonne pour inclure un exemple concret dans le monde réel. – systemovich

1

Pour moi « Voulez-vous utiliser l'objet Etat Singleton, Fonction Vous voulez utiliser la méthode statique »

Cela dépend de ce que vous voulez. Chaque fois que vous voulez l'état de l'objet (par exemple polymorphisme comme état nul au lieu de null, ou état par défaut), singleton est le choix approprié pour vous alors que la méthode statique utilise quand vous avez besoin de fonction (recevoir les entrées puis retourner une sortie).

Je recommande pour le cas singleton, il devrait toujours être le même état après son instanciation. Il ne doit pas non plus être clonable, ni recevoir de valeur à définir (sauf configuration statique à partir du fichier par exemple propriétés fichier dans java).

P.S. Les performances entre ces 2 sont différentes en millisecondes, alors concentrez-vous d'abord sur Architecture.

Questions connexes