Différence entre classe statique et motif singleton?

1769

Quelle différence réelle (c'est-à-dire pratique) existe entre une classe statique et un modèle singleton?

Les deux peuvent être invoqués sans instanciation, les deux ne fournissent qu'une seule "instance" et aucun d'eux n'est thread-safe. Y a-t-il une autre différence?

Jorge Córdoba
la source
4
Selon l'implémentation du langage et vos modèles d'utilisation, un Singleton peut être moins efficace en raison de la surcharge d'appeler la getInstance()méthode chaque fois que vous souhaitez l'utiliser (bien que dans la plupart des cas, cela n'a pas d'importance ).
trop de php le
5
Il y a déjà beaucoup de réponses. Il s'agit en fait d'un singletonobjet où les staticméthodes ne sont que des fonctions, une entité non OO.
fastcodejava
4
Dépend de la mise en œuvre .. csharpindepth.com/Articles/General/Singleton.aspx
VJAI
4
Il y a une différence lorsque vous souhaitez autoriser des tiers à fournir l'implémentation de la classe. Dans ce cas, vous avez généralement besoin d'un modèle d'usine également. Voir agiletribe.wordpress.com/2013/10/08/…
AgilePro
IMO cette réponse le résume très bien stackoverflow.com/questions/14097656/…
Dave

Réponses:

1251

Qu'est-ce qui vous fait dire qu'un singleton ou une méthode statique n'est pas thread-safe? Habituellement, les deux doivent être implémentés pour être thread-safe.

La grande différence entre un singleton et un tas de méthodes statiques est que les singletons peuvent implémenter des interfaces (ou dériver de classes de base utiles, bien que ce soit moins courant, selon mon expérience), vous pouvez donc contourner le singleton comme s'il s'agissait "juste d'un autre" " la mise en oeuvre.

Jon Skeet
la source
29
Eh bien, si vous le préférez, ni l'un ni l'autre n'est intrinsèquement threadsafe, vous devez les faire être threadsafe, les deux, donc aucune différence là-bas.
Jorge Córdoba
119
Pouvez-vous donner un exemple de quelque chose qui est intrinsèquement threadsafe, autre que les types immuables?
Jon Skeet
26
Pour Skeet: Les gens qui disent que singleton n'est pas threadsafe signifient qu'un singleton est partagé entre les threads inutilement tout le temps, tandis que les objets de pile sont partagés lorsque vous en avez besoin, ce qui signifie que vous n'avez pas à faire de synchronisation inutile.
45
@Geek: Imaginez que le singleton implémente une interface Foo, et vous avez une méthode prenant un Foocomme paramètre. Avec cette configuration, les appelants peuvent choisir d'utiliser le singleton comme implémentation - ou ils peuvent utiliser une implémentation différente. La méthode est découplée du singleton. Comparez cela avec la situation où la classe n'a que des méthodes statiques - chaque morceau de code qui veut appeler ces méthodes est étroitement couplé à la classe, car il doit spécifier quelle classe contient les méthodes statiques.
Jon Skeet
10
@AmirBareket: Ce n'est cependant pas un singleton selon le modèle de conception singleton - si la classe elle-même permet la création de plusieurs instances, ce n'est pas un IMO singleton, quelle que soit la fonction de l'usine.
Jon Skeet
476

La vraie réponse est par Jon Skeet, sur un autre forum ici .

Un singleton permet d'accéder à une seule instance créée - cette instance (ou plutôt, une référence à cette instance) peut être passée en paramètre à d'autres méthodes et traitée comme un objet normal.

Une classe statique n'autorise que les méthodes statiques.

Kezzer
la source
64
Pourquoi voudriez-vous passer un Singleton en tant que paramètre, si vous pouvez accéder à la même instance de n'importe où en appelant la méthode statique getInstance ()?
Henrique Ordine
23
@HenriqueOrdine Donc, il peut s'intégrer dans le code existant et fournir une interface?
6
@HenriqueOrdine Ils parlent de classe statique, pas d'une classe avec des méthodes statiques. La classe statique ne peut pas être instanciée. Néanmoins, si vous passez une instance d'une classe (non statique) qui contient des méthodes statiques, vous ne pouvez pas appeler de méthodes statiques sur une instance.
Goran
3
Qu'est-ce qu'une classe statique? Au moins en Java, il n'y a rien de tel.
Henrique Ordine
16
@Goran Au départ, j'étais très confus par votre formulation. Vous avez dit "vous ne pouvez pas appeler des méthodes statiques sur une instance". J'ai lu cela comme "si vous avez une référence à un objet instancié, vous ne pouvez pas appeler les méthodes statiques qu'il pourrait avoir." C'est bien sûr incorrect. Après l'avoir relu à quelques reprises, je pense que vous vouliez dire "de l'intérieur des méthodes statiques, vous ne pouvez pas accéder aux objets non statiques de la classe", ce qui est correct. Je tiens à préciser que pour toute personne nouvelle dans ces concepts qui tombe sur cette réponse et lit vos commentaires.
Andrew Steitz
359
  1. Les objets singleton sont stockés dans le tas , mais les objets statiques sont stockés dans la pile .
  2. Nous pouvons cloner (si le concepteur ne l'a pas interdit) l'objet singleton, mais nous ne pouvons pas cloner l'objet de classe statique.
  3. Les classes singleton suivent les POO (principes orientés objet), pas les classes statiques.
  4. Nous pouvons implémenter un interfaceavec une classe Singleton, mais pas les méthodes statiques d'une classe (ou par exemple un C # static class).
Vadluri Sreenu
la source
100
La deuxième affirmation est fausse. Nous ne pouvons pas cloner un objet Singleton. L'implémentation Singleton doit refuser cela. Si vous pouvez vraiment cloner Singleton, ce n'est pas Singleton.
Alexander Yancharuk
19
Cette réponse n'est pas correcte pour Java: ni le singleton ni le statique n'utilisent la pile.
AgilePro
72
Le n ° 1 n'est pas important. # 2 décrit une implémentation défectueuse. # 3 est complètement injustifiable.
Casey
31
Comment un objet statique peut-il être stocké dans la pile? Un nouveau cadre de pile est créé lorsque vous appelez une méthode, il stocke les variables locales de la méthode, ce cadre de pile est supprimé lorsque la méthode revient et ces variables locales sont perdues. Bien sûr, la pile est rapide, mais elle ne convient pas pour stocker des objets statiques.
mike_m
23
Je ne peux pas comprendre le nombre de votes positifs sur celui-ci. 1) Pourquoi Singleton devrait-il être stocké en pile? Dans les langages gérés comme C # ou Java, les données sont stockées dans un tas géré, à l'exception des variables / paramètres de méthode locale. 2) Si vous pouvez le cloner, ce n'est pas un singleton correctement implémenté. 3) Singleton est connu comme un anti-modèle OOP; c'est-à-dire quelque chose que vous devriez éviter si possible. 4) C'est la seule chose correcte.
Groo
152

Le modèle Singleton présente plusieurs avantages par rapport aux classes statiques. Tout d'abord, un singleton peut étendre des classes et implémenter des interfaces, contrairement à une classe statique (il peut étendre des classes, mais il n'hérite pas de leurs membres d'instance). Un singleton peut être initialisé paresseusement ou de manière asynchrone tandis qu'une classe statique est généralement initialisée lors de son premier chargement, ce qui peut entraîner des problèmes potentiels de chargeur de classe. Cependant, l'avantage le plus important est que les singletons peuvent être gérés de manière polymorphe sans forcer leurs utilisateurs à supposer qu'il n'y a qu'une seule instance.

neil.johnson
la source
10
+1 pour les bons points pragmatiques. Le motif singleton est surutilisé en général, mais il y a quelques situations où il convient. Voir aussi: agiletribe.wordpress.com/2013/10/08/…
AgilePro
3
Vous avez raison sur l'avantage d'être polymorphe. C'est le point le plus important
Ahmad
La classe statique imbriquée peut implémenter l'interface. Essayez de le coder, cela fonctionnera. J'ai pu compiler le code sans aucune erreur.
nanosoft
75

staticles classes ne sont pas pour tout ce qui a besoin d'état. Il est utile pour rassembler un tas de fonctions, c'est-à-dire Math(ou Utilsdans des projets). Ainsi, le nom de classe nous donne juste un indice où nous pouvons trouver les fonctions et rien de plus.

Singletonest mon modèle préféré et je l'utilise pour gérer quelque chose en un seul point. Il est plus flexible que les staticclasses et peut maintenir son état. Il peut implémenter des interfaces, hériter d'autres classes et autoriser l'héritage.

Ma règle pour choisir entre staticet singleton:

S'il y a un tas de fonctions qui devraient être maintenues ensemble, alors staticc'est le choix. Tout ce qui nécessite un accès unique à certaines ressources, pourrait être implémenté comme singleton.

Xaqron
la source
16
Pourquoi les classes statiques ne devraient-elles rien faire qui doive sauver l'état?
Trisped
12
@ Trisped: Vous n'avez ni contrôle précis sur l'initialisation ni la finalisation.
Xaqron
7
vous m'avez perdu à "Singleton est mon modèle préféré". Singleton est un coin si pointu qu'il devrait être considéré comme un anti-motif ainsi qu'un motif. Les classes peuvent bien avoir des états statiques, c'est aussi un accès unique, si quelque chose d'état statique est plus "à accès unique" que les singletons parce que la plupart des implémentations singleton sont cassées. vous pouvez cloner le singleton, tandis que statique est béni par la définition d'être unique.
PoweredByRice
1
Que signifie maintenir l'état? Qu'est-ce que l'état?
Kyle Delaney
2
@KyleDelaney: Il States'agit simplement de la combinaison de différentes propriétés d'un objet qui changent généralement avec le temps. Vous pouvez Google pour une définition formelle.
Xaqron
65

Classe statique: -

  1. Vous ne pouvez pas créer l'instance de classe statique.

  2. Chargé automatiquement par le Common Language Runtime (CLR) .NET Framework lorsque le programme ou l'espace de noms contenant la classe est chargé.

  3. La classe statique ne peut pas avoir de constructeur.

  4. Nous ne pouvons pas passer la classe statique à la méthode.

  5. Nous ne pouvons pas hériter la classe Static d'une autre classe Static en C #.

  6. Une classe ayant toutes les méthodes statiques.

  7. Meilleures performances (les méthodes statiques sont liées au moment de la compilation)

Singleton:-

  1. Vous pouvez créer une instance de l'objet et la réutiliser.

  2. L'instance singleton est créée pour la première fois lorsque l'utilisateur l'a demandé.

  3. La classe singleton peut avoir un constructeur.

  4. Vous pouvez créer l'objet de la classe singleton et le passer à la méthode.

  5. La classe Singleton ne dit aucune restriction d'héritage.

  6. Nous pouvons disposer des objets d'une classe singleton mais pas d'une classe statique.

  7. Les méthodes peuvent être remplacées.

  8. Peut être chargé paresseux en cas de besoin (les classes statiques sont toujours chargées).

  9. Nous pouvons implémenter l'interface (la classe statique ne peut pas implémenter d'interface).

RajeshVerma
la source
13
Les classes statiques ont des constructeurs: msdn.microsoft.com/en-us/library/k9x6w0hc.aspx
Tomer Arazy
2
Oui, statique peut avoir un constructeur qui est interne à cette classe. Cela est invoqué lorsqu'une méthode statique de la classe est appelée.
rahulmr
Pour singleton au moment de la compilation, il est stocké dans la mémoire HEAP mais s'il est instancié une fois, est-il stocké dans STACK?
Luminous_Dev
@Luminous_Dev Non. Toute instance singleton est une instance d'objet à la fin de la journée. Il sera sans aucun doute stocké sur le tas.
RBT
1
@rahulmr Distinction importante: le constructeur est également appelé avant la création de la première instance (AKA uniquement).
CoolOppo
53

Une classe statique est une classe qui n'a que des méthodes statiques, pour lesquelles un meilleur mot serait "fonctions". Le style de conception incarné dans une classe statique est purement procédural.

Singleton, d'autre part, est un motif spécifique à la conception OO. Il s'agit d'une instance d'un objet (avec toutes les possibilités inhérentes à cela, comme le polymorphisme), avec une procédure de création qui garantit qu'il n'y a qu'une seule instance de ce rôle particulier sur toute sa durée de vie.

Morendil
la source
1
le polymorphisme n'entre pas du tout en jeu avec les singletons
32
Alors tu crois. Je pense différemment. ;) Par exemple, imaginez une usine singleton qui retourne une interface. Vous savez que vous obtenez un ISingleton (et c'est le même pour toujours) mais pas nécessairement quelle implémentation.
Morendil
La classe statique imbriquée peut également avoir des méthodes d'instance, il n'est pas restreint d'avoir uniquement des méthodes statiques. Codez-la et vous pouvez voir.
nanosoft
Dans les langages avec un modèle d'objet plus agréable (par exemple Ruby), les classes sont aussi des objets. L'aspect "purement procédural" d'une classe statique est une restriction arbitraire imposée par le langage.
Max
36

Dans le modèle singleton, vous pouvez créer le singleton comme une instance d'un type dérivé, vous ne pouvez pas le faire avec une classe statique.

Exemple rapide:

if( useD3D )
    IRenderer::instance = new D3DRenderer
else
    IRenderer::instance = new OpenGLRenderer
Don Neufeld
la source
39
Ce n'est pas vraiment un motif singleton, ça ressemble plus à de l'usine pour moi.
vava
10
Pas vraiment, la différence fondamentale entre les deux est que le Singleton "mettra en cache" son objet unique et continuera à renvoyer (une référence à) le même. Le modèle Factory créera de nouvelles instances.
Mystic
12
Alors c'est proxy-singleton :)
vava
3
Hmm, je connais cette variété de Singleton sous le nom de MonoState.
Huppie
l'exemple est le modèle d'usine
Rajavel D
26

Pour développer la réponse de Jon Skeet

La grande différence entre un singleton et un tas de méthodes statiques est que les singletons peuvent implémenter des interfaces (ou dériver de classes de base utiles, bien que ce soit un IME moins courant), vous pouvez donc contourner le singleton comme s'il s'agissait d'une implémentation "juste une autre".

Les singletons sont plus faciles à utiliser lors des tests unitaires d'une classe. Partout où vous passez des singletons en tant que paramètre (constructeurs, setters ou méthodes), vous pouvez à la place substituer une version simulée ou tronquée du singleton.

Mike Rylander
la source
Je ne pense pas que vous puissiez vous moquer directement d'un singleton. N'auriez-vous pas à déclarer une interface que le singleton et la classe fictive implémentent tous les deux?
Ellen Spertus,
@espertus Pourquoi ne pouvez-vous pas vous moquer de votre singleton? Exemple utilisant mockito MySingleton mockOfMySingleton = mock(MySingleton.class).
Mike Rylander
vous avez raison, vous pouvez vous en moquer avec des outils comme le mockito qui utilisent la réflexion. Je voulais dire que vous ne pouvez pas vous moquer directement de lui en le sous-classant et en remplaçant ses méthodes.
Ellen Spertus
@espertus Pourquoi pas? Lorsque vous instanciez l'objet que vous testez, vous pouvez remplacer l'implémentation de sous-classe de votre singleton là où vous auriez utilisé l'original. Ex:new ClazzToTest(mockSingleton);
Mike Rylander
Je n'ai pas utilisé Mockito, mais comment pouvez-vous sous-classer une classe qui a un constructeur privé, ce qui est le cas pour les singletons, sauf en utilisant la réflexion? Discussions connexes: stackoverflow.com/questions/2302179/mocking-a-singleton-class stackoverflow.com/questions/15939023/…
Ellen Spertus
23

Voici un bon article: http://javarevisited.blogspot.com.au/2013/03/difference-between-singleton-pattern-vs-static-class-java.html

Classes statiques

  • une classe ayant toutes les méthodes statiques .
  • meilleures performances (les méthodes statiques sont liées au moment de la compilation)
  • ne peut pas remplacer les méthodes, mais peut utiliser le masquage des méthodes. ( Que cache la méthode en Java? Même l'explication JavaDoc prête à confusion )

    public class Animal {
        public static void foo() {
            System.out.println("Animal");
        }
    }
    
    public class Cat extends Animal {
        public static void foo() {  // hides Animal.foo()
            System.out.println("Cat");
        }
    }
    

Singleton

En résumé, je n'utiliserais que des classes statiques pour conserver les méthodes util et utiliser Singleton pour tout le reste.


Modifications

JackDev
la source
4
Je ne connais pas Java, mais dans .Net, vos deux derniers points sont incorrects. Les classes statiques peuvent référencer des propriétés et des champs statiques, donc à condition qu'ils soient égaux. Et ils sont chargés paresseusement - le constructeur statique est exécuté lorsque: 1) Une instance de la classe est créée. 2) Tous les membres statiques de la classe sont référencés. 1 ne s'applique pas, ce qui laisse 2. Ainsi, une classe statique n'est pas chargée jusqu'à la première fois qu'elle est utilisée.
jmoreno
1
Pour la classe statique, bien que vous ne puissiez pas remplacer la méthode statique, vous pouvez masquer la méthode statique à son parent.
Max Peng
si Animal animal = new Cat();alors animal.foo();que se passe-t-il?
Luminous_Dev
La classe statique @jmoreno n'est pas chargée avant la première utilisation? Je crois qu'il est stocké dans la mémoire de la pile au moment de la compilation. Et il est accessible instantanément .. n'est-ce pas?
Luminous_Dev
@Luminous_Dev: au moins pour .net, une classe statique a un constructeur qui s'exécute lors du premier accès, donc non, il n'est pas instantanément accessible. Le constructeur statique pourrait en théorie prendre un temps illimité. Où il (ou toute autre classe est stockée) est un détail d'implémentation, ce n'est pas vraiment pertinent pour cette question.
jmoreno
22

Un autre avantage d'un singleton est qu'il peut facilement être sérialisé, ce qui peut être nécessaire si vous avez besoin de sauvegarder son état sur disque ou de l'envoyer quelque part à distance.

Alex
la source
19

Je ne suis pas un grand théoricien de l'OO, mais d'après ce que je sais, je pense que la seule fonctionnalité OO qui manque aux classes statiques par rapport aux singletons est le polymorphisme. Mais si vous n'en avez pas besoin, avec une classe statique, vous pouvez bien sûr avoir l'héritage (pas sûr de l'implémentation de l'interface) et l'encapsulation des données et des fonctions.

Le commentaire de Morendil, "Le style de conception incarné dans une classe statique est purement procédural" Je peux me tromper, mais je ne suis pas d'accord. Dans les méthodes statiques, vous pouvez accéder aux membres statiques, qui seraient exactement les mêmes que les méthodes singleton accédant à leurs membres d'instance unique.

edit:
Je pense en fait maintenant qu'une autre différence est qu'une classe statique est instanciée au démarrage du programme * et vit tout au long de la durée de vie du programme, tandis qu'un singleton est explicitement instancié à un moment donné et peut également être détruit.

* ou il peut être instancié à la première utilisation, selon la langue, je pense.

Petruza
la source
15
Oui, tout le monde semble ignorer le fait qu'une classe avec des méthodes statiques peut également avoir des champs statiques privés qu'elle peut toujours utiliser pour maintenir l'état (et exposer certains d'entre eux au code client via des setters / getters statiques publics).
user289463
17

Pour illustrer le point de Jon, ce qui est montré ci-dessous ne peut pas être fait si Logger était une classe statique. La classe SomeClasss'attend à ce qu'une instance d' ILoggerimplémentation soit passée dans son constructeur.

La classe singleton est importante pour que l'injection de dépendances soit possible.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {

            var someClass = new SomeClass(Logger.GetLogger());
        }


    }

    public class SomeClass 
    {
        public SomeClass(ILogger MyLogger)
        {

        }
    }

    public class Logger : ILogger
    {
        private static Logger _logger;
        private Logger() { }

        public static Logger GetLogger()
        {
            if (_logger==null)
            {
                _logger = new Logger();
            }

            return _logger;
        }

        public void Log()
        {

        }

    }


    public interface ILogger
    {
         void Log();
    }
}
developer747
la source
13

Un singleton est juste une classe normale qui EST instanciée mais juste une fois et indirectement à partir du code client. La classe statique n'est pas instanciée. Autant que je sache, les méthodes statiques (la classe statique doit avoir des méthodes statiques) sont plus rapides que les méthodes non statiques.

Edit:
FxCop Performance rule description: "Les méthodes qui n'accèdent pas aux données d'instance ou aux méthodes d'instance d'appel peuvent être marquées comme statiques (partagées dans VB). Après cela, le compilateur émettra des sites d'appel non virtuels vers ces membres, ce qui empêchera un vérifier à l'exécution pour chaque appel qui garantit que le pointeur d'objet actuel n'est pas nul. Cela peut entraîner un gain de performances mesurable pour le code sensible aux performances. Dans certains cas, l'échec de l'accès à l'instance d'objet actuelle représente un problème de correction. "
Je ne sais pas vraiment si cela s'applique également aux méthodes statiques dans les classes statiques.

agnieszka
la source
11

Les singleton sont instanciés, c'est juste qu'il n'y a qu'une seule instance jamais instanciée, d'où le single de Singleton.

Une classe statique ne peut pas être instanciée par autre chose que lui-même.

Kezzer
la source
La classe statique peut être très instanciée en Java. Lisez docs.oracle.com/javase/tutorial/java/javaOO/nested.html. Référez également ma réponse stackoverflow.com/a/37114702/1406510
nanosoft
8

Les principales différences sont les suivantes:

  • Singleton a une instance / un objet tandis que la classe statique est un tas de méthodes statiques
  • Singleton peut être étendu par exemple via une interface alors que la classe statique ne peut pas l'être.
  • Le singleton peut être hérité, ce qui prend en charge les principes d'ouverture / fermeture dans les principes SOLID, par contre, la classe statique ne peut pas être héritée et nous devons apporter des modifications en soi.
  • L'objet singleton peut être passé aux méthodes tandis que la classe statique car il n'a pas d'instance ne peut pas être passée en tant que paramètres
Faran Shabbir
la source
7

Singleton est une meilleure approche du point de vue des tests. Contrairement aux classes statiques, singleton peut implémenter des interfaces et vous pouvez utiliser une instance fictive et les injecter.

Dans l'exemple ci-dessous, je vais illustrer cela. Supposons que vous ayez une méthode isGoodPrice () qui utilise une méthode getPrice () et que vous implémentiez getPrice () comme méthode dans un singleton.

singleton qui fournit la fonctionnalité getPrice:

public class SupportedVersionSingelton {

    private static ICalculator instance = null;

    private SupportedVersionSingelton(){

    }

    public static ICalculator getInstance(){
        if(instance == null){
            instance = new SupportedVersionSingelton();
        }

        return instance;
    }

    @Override
    public int getPrice() {
        // calculate price logic here
        return 0;
    }
}

Utilisation de getPrice:

public class Advisor {

    public boolean isGoodDeal(){

        boolean isGoodDeal = false;
        ICalculator supportedVersion = SupportedVersionSingelton.getInstance();
        int price = supportedVersion.getPrice();

        // logic to determine if price is a good deal.
        if(price < 5){
            isGoodDeal = true;
        }

        return isGoodDeal;
    }
}


In case you would like to test the method isGoodPrice , with mocking the getPrice() method you could do it by:
Make your singleton implement an interface and inject it. 



  public interface ICalculator {
        int getPrice();
    }

Mise en œuvre finale de Singleton:

public class SupportedVersionSingelton implements ICalculator {

    private static ICalculator instance = null;

    private SupportedVersionSingelton(){

    }

    public static ICalculator getInstance(){
        if(instance == null){
            instance = new SupportedVersionSingelton();
        }

        return instance;
    }

    @Override
    public int getPrice() {
        return 0;
    }

    // for testing purpose
    public static void setInstance(ICalculator mockObject){
        if(instance != null ){
instance = mockObject;
    }

classe de test:

public class TestCalculation {

    class SupportedVersionDouble implements ICalculator{
        @Override
        public int getPrice() { 
            return 1;
        }   
    }
    @Before
    public void setUp() throws Exception {
        ICalculator supportedVersionDouble = new SupportedVersionDouble();
        SupportedVersionSingelton.setInstance(supportedVersionDouble);

    }

    @Test
    public void test() {
          Advisor advidor = new Advisor();
          boolean isGoodDeal = advidor.isGoodDeal();
          Assert.assertEquals(isGoodDeal, true);

    }

}

Dans le cas où nous prenons l'alternative d'utiliser la méthode statique pour implémenter getPrice (), il était difficile de se moquer de getPrice (). Vous pouvez vous moquer de l'électricité statique avec Power Mock, mais tous les produits ne peuvent pas l'utiliser.

Amir Bareket
la source
1
Ce n'est désormais plus sûr pour les threads, et généralement désagréable en termes de la façon dont vous accédez à l'implémentation de l'interface. Bien sûr, avoir une interface est agréable pour la testabilité - mais alors pourquoi s'embêter avec un singleton? Évitez simplement d'avoir un singleton du tout; avoir une classe l'implémentant à des fins de production, une implémentation à des fins de test et injecter la bonne instance en fonction de ce que vous faites. Pas besoin de coupler le singleton à ses appelants.
Jon Skeet
Merci pour les commentaires. il est très simple de le rendre sûr pour les threads. en outre, j'utilise singleton à des fins de mise en cache.
Amir Bareket
1
Oui, bien qu'avec des frais généraux inutiles. Encore une fois, il est plus simple de ne pas utiliser de singleton.
Jon Skeet
6

Je suis d'accord avec cette définition:

Le mot " célibataire " " signifie un seul objet tout au long du cycle de vie de l'application, la portée est donc au niveau de l'application.

La statique n'a pas de pointeur d'objet, la portée est donc au niveau du domaine d'application.

De plus, les deux doivent être implémentés pour être thread-safe.

Vous pouvez trouver d'autres différences intéressantes à propos de: Motif singleton contre classe statique

Alessandro Ornano
la source
5

Une différence notable est l'instanciation différée qui accompagne les singletons.

Avec les classes statiques, il est créé par le CLR et nous n'avons aucun contrôle dessus. avec les singletons, l'objet est instancié sur la première instance à laquelle il a tenté d'accéder.

Eranga Dissanayaka
la source
4

Dans de nombreux cas, ces deux n'ont aucune différence pratique, surtout si l'instance singleton ne change jamais ou change très lentement, par exemple en maintenant les configurations.

Je dirais que la plus grande différence est qu'un singleton est toujours un bean Java normal contrairement à une classe Java spécialisée uniquement statique. Et pour cette raison, un singleton est accepté dans de nombreuses autres situations; il s'agit en fait de la stratégie d'instanciation de Spring Framework par défaut. Le consommateur peut ou non savoir qu'il s'agit d'un singleton transmis, il le traite simplement comme un bean Java normal. Si les exigences changent et qu'un singleton doit devenir un prototype à la place, comme nous le voyons souvent au printemps, cela peut être fait de manière totalement transparente sans modification de ligne de code pour le consommateur.

Quelqu'un d'autre a mentionné plus tôt qu'une classe statique devrait être purement procédurale, par exemple java.lang.Math. Dans mon esprit, une telle classe ne devrait jamais être transmise et elle ne devrait jamais contenir autre chose que final statique comme attributs. Pour tout le reste, utilisez un singleton car il est beaucoup plus flexible et plus facile à entretenir.

Chris
la source
4

Nous avons notre infrastructure de base de données qui établit des connexions avec le back-end. Pour éviter les lectures sales sur plusieurs utilisateurs, nous avons utilisé un modèle singleton pour nous assurer d'avoir une seule instance disponible à tout moment.

En c #, une classe statique ne peut pas implémenter une interface. Lorsqu'une classe d'instance unique doit implémenter une interface à des fins commerciales ou IoC, c'est là que j'utilise le modèle Singleton sans classe statique

Singleton fournit un moyen de maintenir l'état dans des scénarios sans état

J'espère que cela vous aide ..

RK_Muddala
la source
3
  1. Chargement paresseux
  2. Prise en charge des interfaces, de sorte qu'une implémentation distincte peut être fournie
  3. Possibilité de renvoyer le type dérivé (en tant que combinaison de lazyloading et d'implémentation d'interface)
Tilak
la source
La classe statique imbriquée peut très bien implémenter l'interface en java. Votre deuxième point est faux.
nanosoft
3

une. Sérialisation - Les membres statiques appartiennent à la classe et ne peuvent donc pas être sérialisés.

b. Bien que nous ayons rendu le constructeur privé, les variables membres statiques seront toujours portées dans la sous-classe.

c. Nous ne pouvons pas faire d'initialisation paresseuse car tout sera chargé lors du chargement de classe uniquement.

Vivek Vermani
la source
3

Du point de vue du client, le comportement statique est connu du client, mais le comportement Singleton peut être complété caché d'un client. Le client peut ne jamais savoir qu'il n'y a qu'une seule instance avec laquelle il joue encore et encore.

Arpit Khandelwal
la source
3

J'ai lu ce qui suit et je pense que cela a également du sens:

S'occuper des affaires

N'oubliez pas que l'une des règles OO les plus importantes est qu'un objet est responsable de lui-même. Cela signifie que les problèmes concernant le cycle de vie d'une classe doivent être traités dans la classe, et non délégués à des constructions de langage comme static, etc.

extrait du livre Objected-Oriented Thought Process 4th Ed.

non-polarité
la source
Je ne serais pas d'accord, car cela ajoute vraiment une responsabilité à la classe, ce qui (en supposant qu'il fasse quoi que ce soit) signifie qu'il viole maintenant le principe de responsabilité unique.
ssmith
3

Dans un article que j'ai écrit, j'ai décrit mon point de vue sur la raison pour laquelle le singleton est bien meilleur qu'une classe statique:

  1. La classe statique n'est pas réellement une classe canonique - c'est un espace de noms avec des fonctions et des variables
  2. L'utilisation d'une classe statique n'est pas une bonne pratique en raison de la rupture des principes de programmation orientée objet
  3. La classe statique ne peut pas être transmise en tant que paramètre pour d'autres
  4. La classe statique ne convient pas pour une initialisation «paresseuse»
  5. L'initialisation et l'utilisation de la classe statique sont toujours difficiles à suivre
  6. La mise en œuvre de la gestion des threads est difficile
Paul R
la source
Je le rafraîchirais pour la grammaire anglaise, mais sinon, c'est une lecture intéressante :)
Noctis
3
  1. Nous pouvons créer l'objet de la classe singleton et le passer à la méthode.

  2. La classe singleton n'a aucune restriction d'héritage.

  3. Nous ne pouvons pas disposer des objets d'une classe statique mais pouvons singleton classe.

Sanjay Dwivedi
la source
Quelle est l'utilité de passer un singleton dans une méthode s'il n'y en a toujours qu'un et que celui-ci a toujours une référence statique?
Aaron Franke
3

Distinction de la classe statique

JDK a des exemples de singleton et de statique, d'une part java.lang.Mathest une classe finale avec des méthodes statiques, d'autre partjava.lang.Runtime est une classe de singleton.

Avantages de singleton

  • Si votre besoin de maintenir l'état plutôt que le modèle singleton est un meilleur choix que la classe statique, parce que le maintien de l'état dans la classe statique entraîne des bogues, en particulier dans un environnement simultané, cela peut conduire à des conditions de concurrence sans modification parallèle de synchronisation adéquate par plusieurs threads.

  • La classe singleton peut être chargée paresseusement s'il s'agit d'un objet lourd, mais la classe statique n'a pas de tels avantages et toujours chargée avec impatience.

  • Avec singleton, vous pouvez utiliser l'héritage et le polymorphisme pour étendre une classe de base, implémenter une interface et fournir différentes implémentations.

  • Étant donné que les méthodes statiques en Java ne peuvent pas être remplacées, elles conduisent à l'inflexibilité. D'autre part, vous pouvez remplacer les méthodes définies dans la classe singleton en l'étendant.

Inconvénients de la classe statique

  • Il est plus facile d'écrire un test unitaire pour singleton que pour une classe statique, car vous pouvez passer un objet simulé chaque fois que singleton est attendu.

Avantages de la classe statique

  • La classe statique offre de meilleures performances que singleton, car les méthodes statiques sont liées au moment de la compilation.

Il existe plusieurs réalisations de motif singleton chacune avec des avantages et des inconvénients.

  • Désireux de charger singleton
  • Double verrouillage à double vérification
  • Idiome du titulaire d'initialisation à la demande
  • Le singleton basé sur l'énumération

La description détaillée de chacun d'eux est trop verbeuse donc je viens de mettre un lien vers un bon article - Tout ce que vous voulez savoir sur Singleton

Oleg Poltoratskii
la source
2

Il existe une énorme différence entre une seule instance de classe statique (c'est-à-dire une seule instance d'une classe, qui se trouve être une variable statique ou globale) et un pointeur statique unique vers une instance de la classe sur le tas:

Lorsque votre application se ferme, le destructeur de l'instance de classe statique sera appelé. Cela signifie que si vous avez utilisé cette instance statique comme singleton, votre singleton a cessé de fonctionner correctement. S'il y a toujours du code en cours d'exécution qui utilise ce singleton, par exemple dans un thread différent, ce code risque de se bloquer.

gnasher729
la source
1
Donc, si l'application se ferme, Singleton restera-t-il en mémoire?
nanosoft
Je pense que vous voulez dire lorsque votre thread actuel se termine, pas l'application, non? Si l'application se ferme, il n'y a aucun moyen pour un autre thread d'en utiliser quoi que ce soit.
Tom Brito
2

La différence dans ma tête est l'implémentation d'une programmation orientée objet (Singleton / Prototype) ou d'une programmation fonctionnelle (Statique).

Nous sommes trop concentrés sur le nombre d'objets créés par le motif singleton alors que nous devrions nous concentrer sur le fait qu'à la fin nous détenons un objet. Comme d'autres l'ont déjà dit, il peut être étendu, passé en paramètre mais surtout il est plein d'état.

D'un autre côté, statique est utilisé pour implémenter une programmation fonctionnelle. Les membres statiques appartiennent à une classe. Ils sont apatrides.

Au fait, saviez-vous que vous pouvez créer des classes statiques singleton :)

Atif Karbelkar
la source
Quel est l'intérêt de passer un singleton comme paramètre car il a toujours une référence statique sur la classe?
Aaron Franke