IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Dotnet Discussion :

singleton vs static


Sujet :

Dotnet

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    343
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 343
    Points : 129
    Points
    129
    Par défaut singleton vs static
    Bonjour,

    Qu'est ce qui est mieux entre:

    - une classe avec des méthodes statiques:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class PersonProvider
    {        
            public static List<PersonEntity> LoadData()
            {
                List<PersonEntity> list = null;
     
                ...
                return list;
            }
    }
    et une classe normale qui s'instancie elle même avec un singleton:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    public class PersonProvider
     {
            private static PersonProvider s_Instance;
            private static object s_InstanceLocker = new object();
     
            // Singleton
            public static PersonProvider Instance
            {
                get
                {
                    lock (s_InstanceLocker)
                    {
                        if (s_Instance == null)
                        {
                            s_Instance = new PersonProvider();
                        }
                        return s_Instance;
                    }
                }
            }
     
            public List<PersonEntity> LoadData()
            {
                List<PersonEntity> list = null;
                ...
                return list;
            }
    }
    Dans le premier cas, j'appelle la classe comme ci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PersonProvider.LoadData();
    Et dans le second:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PersonProvider.Instance.LoadData();
    Merci

  2. #2
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 493
    Points
    5 493
    Par défaut
    Bonjour.

    Dans le cas où la classe statique ne possède aucun champ et n'a pas de constructeur statique, alors elle n'a que des avantages, tant en termes de simplicité de code (déclaration ou appel) qu'en termes de performances (pas besoin de passer this en argument).

    Quand des champs statiques ou un constructeur statique sont présents, il faut simplement être conscient que chaque instanciation de la classe (si celle-ci n'est pas statique) ou appel/référence à un membre statique sera précédé d'un branchement conditionnel pour vérifier que la classe a déjà été initialisée. L'implémentation par la CLR est plus efficace que celle proposée ici puisqu'elle n'a recours un verrouillage que lorsque l'initialisation n'a pas encore été faîte. Et dans 99,99% des cas ces considérations sont secondaires et ne devraient pas être prises en ligne de compte, si bien que la classe statique l'emporte encore.

    Enfin on voit parfois ici ou là certaines personnes critiquer les membres statiques pour des raisons de testabilité, d'accès concurrents, etc. Mais ces critiques s'appliquent aussi à un singleton et puisque ces problèmes n'en sont pas toujours, vouloir les corriger en évitant ces deux motifs (classe statique ou singleton) irait à l'encontre du principe yagni (you ain't gonna need it).

  3. #3
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2011
    Messages
    269
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 269
    Points : 460
    Points
    460
    Par défaut
    Bonjour,

    Tous dépends de ce que font les méthodes de la classe PersonProvider.
    Et vu le nom de la classe, cela dépend surtout de la gestion de la concurrence d'accès.

    Si deux "Update" sur une même personne ne peuvent pas se croiser, alors PersonProvider est une classe qui a besoin d’être instancier. Et le singleton peut répondre à cette instanciation.

    Si ce n'est pas le cas, alors PersonProvider n'a peut être pas besoin d’être instancier, et dans ce cas elle peut directement être marqué comme static
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    public static class PersonProvider 
    { ... }
    J'ajouterai que dans le cas ou une instance serait requis, le singleton n'est pas forcement la solution la plus pérenne.

  4. #4
    Expert confirmé Avatar de Barsy
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    1 484
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 1 484
    Points : 5 279
    Points
    5 279
    Par défaut
    Dans les projets sur lesquels j'ai travaillé, j'ai souvent croisé des classes statiques en .NET et des singletons en Java (les classes statiques n'existent pas en Java).

    Personnellement, je n'ai pas vu de cas où un choix était meilleur que l'autre. Mais peut-être en existe-t-il et je serai curieux de savoir lesquels.
    Je n'ai d'ailleurs par compris ce que tu entends, antoine.debyser, par croiser 2 update sur la même personne.

  5. #5
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Points : 9 742
    Points
    9 742
    Billets dans le blog
    3
    Par défaut
    Les classes statiques et les singletons permettent de partager des objets identiques en mémoire. C'est leur seul point commun. L'usage qui en est fait derrière diffère totalement.

    Le singleton préserve l'aspect "classe" de l'objet. Il permet de ne pas utiliser le mot clef static de partout, et peut implémenter des interfaces. On peut le passer en paramètres ou l'utiliser simplement en tant qu'objet. Ce que l'on ne peut pas faire avec une classe statique.

    Les classes statiques ne permettent pas de définir un comportement précis. On les utilise pour partager des données globales, ou pour effectuer des opérations "génériques", comme par exemple des fonctions mathématiques (addition, multiplication, etc.).

  6. #6
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 493
    Points
    5 493
    Par défaut
    Citation Envoyé par antoine.debyser Voir le message
    Si deux "Update" sur une même personne ne peuvent pas se croiser, alors PersonProvider est une classe qui a besoin d’être instancier. Et le singleton peut répondre à cette instanciation.
    Pour reformuler ceci, dans le cas où l'on souhaite que deux threads voient deux jeux différents de données, alors chacun doit manipuler une instance différente. Dans un tel cas, ni le singleton ni des membres statiques ne conviennent.


    Petit bémol : il est possible de tricher en utilisant l'attribut ThreadStaticAttribute. Avec lui on peut conserver des membres statiques, ou par extension un singleton, tout en faisant en sorte que chaque thread voit des membres statiques/un singleton différents.

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    343
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 343
    Points : 129
    Points
    129
    Par défaut
    Merci à tous pour vos réponses.

    DonQuiche (et les autres), voici tout le code ma classe, sachant que je compte rajouter par la suite des procédures d'ajout, de modification et de suppression:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using DTO;
    using System.Data.SqlClient;
    using System.Configuration;
    using System.Data.Common;
     
    namespace DAL
    {
        public class PersonProvider
        {
            private static PersonProvider s_Instance;
            private static object s_InstanceLocker = new object();
     
            // Singleton
            public static PersonProvider Instance
            {
                get
                {
                    lock (s_InstanceLocker)
                    {
                        if (s_Instance == null)
                        {
                            s_Instance = new PersonProvider();
                        }
                        return s_Instance;
                    }
                }
            }
     
            public List<PersonEntity> LoadData()
            {
                List<PersonEntity> list = null;
     
                using (DbConnection cn = Sql.Instance.GetSqlConnection())
                {
                    using (System.Data.Common.DbCommand cmd = cn.CreateCommand())
                    {
                        cmd.CommandText = "Select * from [VW_PERSONNEL]";
                        cmd.Connection = cn;
     
                        using (System.Data.Common.DbDataReader rdr = cmd.ExecuteReader())
                        {
                            while (rdr.Read())
                            {
                                if (list == null)
                                {
                                    list = new List<PersonEntity>();
                                }
     
                                PersonEntity p = new PersonEntity();
                                p.Id = rdr["ID"] == DBNull.Value ? string.Empty : rdr["ID"].ToString();
                                p.Nom = rdr["NOM"] == DBNull.Value ? string.Empty : rdr["NOM"].ToString();
                                p.Prenom = rdr["PRENOM"] == DBNull.Value ? string.Empty : rdr["PRENOM"].ToString();
     
                                list.Add(p);
                            }
                        }
                    }
                }
     
                return list;
            }
     
        }
     
    }
    Je me suis inspiré de ce tuto sur les développements en couche : ftp://ftp-developpez.com/morpheus/ar...chitecture.pdf

    Au vu de vos réponses, je suis tenté de dire que rendre ma classe statique n'est pas la solution, du moins pas la meilleure solution.

    A noter que dans ma question, ma classe n'était pas déclarée statique : seules les méthodes l'étaient, et je n'ai même pas déclaré de constructeur et je n'ai pas besoin d'en appeler d'ailleurs.
    Bref l'usage du mot statique, en vocabulaire technique me semble un peu utilisé à toutes les sauces.
    Ce que je pense avoir compris, c'est qu'une classe statique, si elle est instanciée, est mise en quelque sorte dans une mémoire "cache".

  8. #8
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 493
    Points
    5 493
    Par défaut
    Citation Envoyé par cyrano_de_bergerac Voir le message
    Ce que je pense avoir compris, c'est qu'une classe statique, si elle est instanciée, est mise en quelque sorte dans une mémoire "cache".
    Pas du tout. ^^

    La seule différence c'est que l'adresse des champs statiques est absolue et connue à l'avance, par opposition aux champs d'instance qui sont relatifs à l'adresse de l'objet lui-même.
    * Lire un champ statique : charger adresse 0x00004327
    * Lire un champ d'instance : charger adresse monInstance + 6

    En substance, c'est tout.
    L'autre petite subtilité c'est qu'avant chaque accès à un champ statique la CLR vérifiera que le constructeur statique a bien été exécuté, d'une façon similaire à ton code pour la propriété Singleton. Ce qui est plutôt secondaire et ne te concerne de toute façon pas si tu n'as pas besoin de champs statiques.


    Partant de là, vu ton usage, la classe statique n'a que des avantages. Le seul intérêt du singleton est à chercher dans la réponse de DotNetMatt : si tu souhaites que PersonProvider puisse implémenter une interface (pour des raison de modularité ou de testabilité) ou hériter d'une classe de base, seul le singleton peut faire ça. La testabilité et la modularité sont plutôt recommandées pour une DAL mais puisque ça ne semble pas être d'actualité, la classe statique s'impose d'elle même.

Discussions similaires

  1. Singleton vs. static ?
    Par BastienCil dans le forum Langages de programmation
    Réponses: 7
    Dernier message: 09/01/2013, 10h35
  2. Réponses: 3
    Dernier message: 21/02/2010, 19h09
  3. Singleton ou static
    Par yannick1717 dans le forum Général Java
    Réponses: 10
    Dernier message: 29/01/2008, 18h02
  4. [Language][Static vs Singleton] Précisions
    Par vincent63 dans le forum Langage
    Réponses: 6
    Dernier message: 14/11/2005, 17h00
  5. singleton et static
    Par elekis dans le forum C++
    Réponses: 2
    Dernier message: 10/09/2005, 16h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo