web-dev-qa-db-fra.com

Pourquoi utiliser un singleton au lieu de méthodes statiques?

Je n'ai jamais trouvé de bonnes réponses à ces questions simples sur les classes d'assistance/utilitaire:

Pourquoi créer 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?

85

Souvent, les singletons sont utilisés pour introduire une sorte de état global dans une application. (Plus souvent que vraiment nécessaire, pour être honnête, mais c'est un sujet pour une autre fois.)

Cependant, il y a quelques cas d'angle où même un sans état singleton peut être utile:

  • Vous vous attendez à le prolonger avec état dans un avenir prévisible.
  • Vous avez besoin d'une instance d'objet pour une raison particulière technique.
    Exemple: objets de synchronisation pour le C # lock ou l'instruction Java synchronized.
  • Vous avez besoin d'héritage, c'est-à-dire que vous voulez pouvoir remplacer facilement votre singleton par un autre en utilisant la même interface mais une implémentation différente.
    Exemple: La méthode Toolkit.getDefaultToolkit() dans Java renverra un singleton dont le type exact dépend du système.
  • Vous voulez égalité de référence pour un valeur sentinelle .
    Exemple: DBNull.Value en C #.
76
Heinzi

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

Si vous avez une classe auxiliaire de fonctions utilitaires 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'assistance via une instance singleton sans état vous permet de contrôler où et comment elle est utilisée, et de la remplacer/la simuler/etc. quand vous en avez besoin.

En faire une instance singleton garantit simplement que vous n'allouez pas plus d'objets du type que nécessaire (puisque vous n'en avez besoin que d'un).

37
tzaman

En fait, 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 se moquer des méthodes d'instance, mais beaucoup d'entre eux ne gèrent pas de manière décente la simulation des méthodes statiques.

15
Sebastien Lorber

Dans la plupart des langages de programmation, les classes échappent à une grande partie du système de types. Bien qu'une classe, avec ses méthodes et variables statiques soit 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, car il ne peut pas être le sous-type d'un autre type. Par exemple, si vous avez une interface IFooable, qui est requise par plusieurs signatures de méthode d'autres classes, l'objet de classe StaticFoo ne peut pas être utilisé à la place de IFooable, tandis que FooSingleton.getInstance() can (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 n'est qu'un cas très particulier du modèle d'usine et doit être traité comme tel. L'utilisation courante en fait plutôt le cas particulier des registres globaux, qui finissent souvent par être mauvais, car les registres globaux ne doivent pas être utilisés à volonté.

Si vous prévoyez de fournir des fonctions d'assistance globales, les méthodes statiques fonctionneront très bien. La classe n'agira pas comme une classe, mais plutôt comme un espace de noms. Je suggère que vous conserviez une cohésion élevée, ou vous pourriez vous retrouver avec les problèmes de couplage les plus étranges.

greetz
back2dos

6
back2dos

Il y a un compromis entre l'utilisation de laquelle. Les singletons peuvent ou non avoir un état et ils se réfèrent à des objets. S'ils ne gardent pas l'état et ne sont utilisés que pour un accès global, la statique est meilleure car ces méthodes seront plus rapides. Mais si vous voulez utiliser des objets et des concepts OOP (polymorphisme d'héritage), alors singleton est mieux.

Prenons un exemple: Java.lang.Runtime est une classe singleton en Java. Cette classe permet 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 différentes implémentations 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 ?

J'espère que ça aide!!

4
Atihska

Pour moi "Want Object State use Singleton, Want Function use static method"

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

Je recommande pour le cas singleton, il devrait toujours être le même état après son instanciation. Il ne doit ni être clonable, ni recevoir de valeur à définir (à l'exception de la configuration statique du fichier, par exemple propriétés fichier en Java).

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

2
Toomtarm Kung

Singleton n'est pas apatride, il détient l'état mondial.

Voici quelques raisons pour lesquelles je peux penser à utiliser Singleton:

  • Pour éviter les fuites de mémoire
  • Pour fournir le même état pour tous les modules dans une application, par exemple une connexion à la base de données
1
Indigo Praveen