Vous aimez ce que vous lisez sur ce blog ?
Envie d'aller plus loin avec véritable formation d'expertise en Java ?
Venez suivre ma formation Masterclasse Expertise Java !

"Même un développeur experimenté a besoin de continuer à apprendre. Et dans cette formation... j'ai appris beaucoup !" - A.G., Java Champion

Sessions intra-entreprises sur demande : contact[at]mokatech.net.
Inscrivez-vous vite !

Java Quiz #14

(Presque) tout le monde connait le pattern suivant :

  1. public class MaClasse implements java.io.Serializable {
  2. private static final MaClasse INSTANCE = new MaClasse();
  3.  
  4. private MaClasse() {
  5. // ...
  6. }
  7.  
  8. public static MaClasse getInstance() {
  9. return INSTANCE;
  10. }
  11.  
  12. private Object readResolve() {
  13. return INSTANCE;
  14. }
  15.  
  16. public void bosseUnPeu() {
  17. // ...
  18. }
  19. }

Avec les dernières versions de Java, y a-t-il une autre manière, beaucoup plus simple et concise, d'implémenter ce pattern de conception ?

Bien sûr, vous avez tous reconnu le pattern "singleton", modifié ici pour supporter la sérialisation et éviter tout conflit d'instances multiples lors d'une désérialisation.

Et qu'est-ce qui, en Java, permet de définir l'ensemble des instances d'une classe au moment de la compilation de celle-ci ? Comme l'a indiqué Bh@Mp0 dans son commentaire : les énumérations, bien sûr !

Peut-on réécrire le pattern "singleton", réécrit à la sauce enum à un seul élément ? Oui, car en Java, une enum est une classe, même si elle a des propriétés et une syntaxe particulières. En particulier, on peut y définir des méthodes spécifiques, comme ceci :

  1. public enum MaClasse {
  2. INSTANCE;
  3.  
  4. public void bosseUnPeu() {
  5. // ...
  6. }
  7. }

Non seulement cette syntaxe est fonctionnellement équivalente à la syntaxe classique (avec un attribut de classe et un constructeur privés, et une opération getInstance() publique), tout en étant plus simple à lire et plus concise, mais en plus, elle inclut gratuitement la gestion de la sérialisation, et elle fournit une protection forte contre les instanciations multiples, y compris via l'introspection ou la sérialisation.

Bref, voilà une manière d'implémenter les singletons en Java qui mériterait de devenir la référence en la matière.


Commentaires

1. Le mardi 24 juin 2008, 10:03 par UnTrucDuGenre
public class MaClasse implements java.io.Serializable {
    private static volatile MaClasse INSTANCE;
    private MaClasse() {
    }

    public static MaClasse getInstance() {
        synchronized(MaClasse.class) {
            if (INSTANCE == null)
                INSTANCE = new MaClasse();
        }
        return INSTANCE;
    }

    private Object readResolve() {
        return INSTANCE;
    }

    public void bosseUnPeu() {
    }
}
2. Le mardi 24 juin 2008, 10:22 par Olivier Croisier

Le code proposé dans le commentaire précédent n'est en rien plus concis que celui de l'énoncé, et pose en plus des problèmes de performance (voir cet article).

Par contre il existe réellement un moyen simple de coder un singleton en Java 5+. Le trouverez-vous ?

3. Le vendredi 27 juin 2008, 11:08 par Bh@Mp0

enum Singleton { INSTANCE; }

Ajouter un commentaire

Le code HTML est affiché comme du texte et les adresses web sont automatiquement transformées.