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

Langage Java Discussion :

[enum] Ecrire un singleton en Java 5.0+


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Inscrit en
    Novembre 2006
    Messages
    129
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 129
    Par défaut [enum] Ecrire un singleton en Java 5.0+
    Bonjour,

    Je trouve l'écriture des singletons en Java relativement chiante, qui plus est quand il s'agit de faire du multithread, et je m'étonne du côté bricolage de la manoeuvre puisqu'à aucun moment la JVM n'est au courant de cette "caractéristique" de la classe...

    N'y a-t-il pas un moyen à l'aide des énumérations de Java 5 de faire que la JVM assure comme une grande l'unicité de l'instance? Je m'explique :

    Au lieu d'utiliser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public class MonSingleton {
      private static MonSingleton instanceUnique;
      private MonSingleton() { ... }
      public static MonSingleton getInstance() {
        if (instanceUnique == null)
          instanceUnique = new MonSingleton();
        return instanceUnique;
      }
    ...
    }
    Utiliser une énumération JSE5 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    public enum MonSingleton {
      INSTANCE;
      MonSingleton() { ... }
     
      // Juste pour faire zoli
      public static MonSingleton getInstance() { return INSTANCE; }
    ...
    }
    Est-ce que c'est une bonne idée? Pourquoi?
    Ou alors j'ai rien compris à l'utilisation des énums?

    Merci les zamis
    ++

  2. #2
    Membre chevronné Avatar de gronono
    Inscrit en
    Novembre 2003
    Messages
    457
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Novembre 2003
    Messages : 457
    Par défaut
    Effectivement, cela peut être une bonne idée.

    Les valeurs des enums ne possèdent qu'une seul instance en théorie.
    Je pense qu'il vaudrait vérifier les spécs concernant les enums pour vérifier que la réalité est la même.

    Il y a quand même un problème sémantique. Le mot clé "enum" indique une énumération. C'est un peu bizarre de voir une énumération contenant une seule valeur et de s'apercevoir qu'en réalité c'est un singleton.

    A+
    Gronono

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Par défaut
    C'est un peu bizarre, certes, mais astucieux ! Cela ne devrait - à priori - pas poser de problème de synchronisation, mais le lazy loading n'est pas possible dans ce cas.

    C'est à dire que typiquement, nous avons exactement la même chose que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class MonSingleton {
      public static final MonSingleton INSTANCE = new MonSingleton();
      public static MonSingleton getInstance () {
        return INSTANCE;
      }
      private MonSingleton () {
        ...
      }
    }

  4. #4
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Je ne vois pas trop l'intérêt d'utiliser une enum


    Pourquoi ne pas simplement utiliser le ClassLoader pour s'assurer de l'unicité du singleton :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class MonSingleton {
    	private static final MonSingleton INSTANCE = new MonSingleton();
     
    	private MonSingleton() {
    		// ...
    	}
     
    	public static MonSingleton getInstance() {
    		return INSTANCE;
    	}
    }
    L'instance du singleton sera créé lors du chargement de la classe...

    a++

    PS : le code du singleton que tu donnes n'est pas thread-safe

    [edit] grillé

  5. #5
    Membre actif
    Inscrit en
    Novembre 2006
    Messages
    129
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 129
    Par défaut
    Pourquoi ne pas simplement utiliser le ClassLoader pour s'assurer de l'unicité du singleton
    ché pa! je trouve ça moche

    sinon merci pour vos réactions, c'est vrai qu'il y avait deux trois trucs auxquels j'avais pas pensé (notamment le cas de l'instanciation on demand )...

    par contre, si ce code n'est pas thread-safe, ça veut dire que les énumérations classiques ne le sont pas non plus?

    du coup, je me pose une autre question plus générale, qu'apportent réellement les énumérations si finalement des membres statiques sont aussi bien?

    en tout cas vous m'enlèverez pas de l'esprit qu'un singleton est un cas particulier d'énumération (essayez donc )

  6. #6
    Membre émérite
    Avatar de divxdede
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    525
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2004
    Messages : 525
    Par défaut
    Ce qui suit est une reflection (je ne sais pas si c'est vrai concernant les enums)

    Un sinleton aujourd'hui peut ne pas l'être selon l'architecture de l'application.
    En effet si l'application met en jeu une hierarchie complexe de classloader (exemple un serveur J2EE avec ces containers) alors ton singleton a de forte chance d'etre instancié plusieurs fois.

    J'image (là commence mon interpretation) qu'un Enum suis les mêmes loi qu'une classe standard vis à vis des classloaders (est-ce vrai ?)
    Dans ce cas plusieurs instances de ton singleton pourront exister pour les même raisons que précedemment.

    Par contre même si MonEnum.INSTANCE == MonEnum.INSTANCE met en jeu deux instances créées par des classLoaders différents, cette égalité retournera "true" car il s'agit d'une spec des Enums.

    Du coups, j'ai l'impression que cette solution est pire que la 1ere dans le sens où même si plusieurs instances existent, tu n'arriveras pas à t'en rendre compte.


    Maintenant, si à l'inverse, les Enum ne suivent pas les mêmes "loi" que les classes normales pour être chargés et que cela permet de se limiter à une instance même dans le cas de plusieurs classloader alors l'interêt est certain.

    Je vais me renseigner sur le fonctionnement interne des Enum car ca a piqué ma curiosité.

    PS: Conceptuellement une entrée d'une Enumeration est logiquement immuable une fois créée, ce qui permet justement d'accepter le "hack" sur l'opérateur == dans le cas de 2 énumerations chargées par des classloaders differents

    EDIT: Mes spéculations / hypothéses qui se révélent fausses (méaculpa)
    Séb.

  7. #7
    Membre expérimenté
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    156
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 156
    Par défaut
    Citation Envoyé par divxdede Voir le message
    Par contre même si MonEnum.INSTANCE == MonEnum.INSTANCE met en jeu deux instances créées par des classLoaders différents, cette égalité retournera "true" car il s'agit d'une spec des Enums.
    C'est faux. Ou as tu lu ça dans les specs ?

  8. #8
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Par défaut
    Citation Envoyé par palnap Voir le message
    par contre, si ce code n'est pas thread-safe, ça veut dire que les énumérations classiques ne le sont pas non plus?
    Il voulait parler de la manière dont tu as implémenté le singleton en utilisant une classe. Le code du singleton-enum est thread-safe, lui.

  9. #9
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par palnap Voir le message
    par contre, si ce code n'est pas thread-safe, ça veut dire que les énumérations classiques ne le sont pas non plus?
    Les enumérations classiques sont thread-safe car elles sont initialisé par le classloader.

    Pour le code non thread-safe je parlais bien sûr de celui-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class MonSingleton {
      private static MonSingleton instanceUnique;
      private MonSingleton() { ... }
      public static MonSingleton getInstance() {
        if (instanceUnique == null)
          instanceUnique = new MonSingleton();
        return instanceUnique;
      }
    ...
    }
    Si tu appelles getInstance() simultanément depuis plusieurs threads alors que l'instance n'est pas créé, tu pourrais entrer plusieurs fois dans le if et donc appeler plusieurs fois le constructeur.



    Citation Envoyé par palnap Voir le message
    du coup, je me pose une autre question plus générale, qu'apportent réellement les énumérations si finalement des membres statiques sont aussi bien?
    La gestion "propre" des énumérations, avec :
    • Une vérification forte des types et des valeurs (impossible de créer des valeurs incorrectes).
    • Gestion des égalités.
    • Gestion propre de la (dé-)sérialisation (sans créer de nouvelle instance).
    • + différents outils facilitant la gestion (l'affichage donne le nom de l'énum et non pas sa valeur, méthode d'accès par nom...)
    • ...



    Citation Envoyé par palnap Voir le message
    en tout cas vous m'enlèverez pas de l'esprit qu'un singleton est un cas particulier d'énumération (essayez donc )
    Peut-être mais la plupart des "fonctionnalités" des enums sont inutiles et il est alors possible de "casser" l'accès en utilisant MonSingleton.INSTANCE au lieu de MonSingleton.getInstance()...


    Citation Envoyé par divxdede Voir le message
    PS: Conceptuellement une entrée d'une Enumeration est logiquement immuable une fois créée,
    Attention une enum n'est pas forcément immuable (même si cela devrait logiquement être le cas) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    	enum MonEnumPasImmuable {
    		VALUE1, VALUE2, VALUE3;
     
    		private int value;
     
    		public int getValue() {
    			return value;
    		}
     
    		public void setValue(int value) {
    			this.value = value;
    		}
    	}
    Par contre la notion d'égalité des enums se base sur l'identité et non pas sur les propriétées des valeurs...


    a++

Discussions similaires

  1. Ecrire log Oracle via java
    Par Diablo_22 dans le forum Persistance des données
    Réponses: 1
    Dernier message: 10/07/2012, 14h20
  2. Ecrire un modèle avec Java
    Par router_ dans le forum Eclipse
    Réponses: 0
    Dernier message: 15/07/2010, 19h15
  3. ecrire le ping en java
    Par ikconde dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 21/03/2007, 13h15

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