Comment créer un singleton en java

Publié le 15 Novembre 2011

Un singleton est une classe qui garantie qu'il n'y aura qu'une seule instance d'elle-même à l'éxecution (donc dans la JVM).

Il existe différentes méthodes pour créer un Singleton en java mais toutes ne sont pas équivalentes:

Certaines privilégient la concision du code mais créent l'instance au démarrage de la JVM ce qui allonge d'autant l'initialisation du programme. D'autres permettent en revanche de créer l'instance seulement lorsqu'on a besoin pour la première fois (on parle alors de lazy-initialisation).

La méthode la plus connue (d'après moi):

public class Singleton{
   
   private static final INSTANCE = new Singleton();
   
   /** private constructor pour être sûr que personne ne pourra créer une instance **/
   private Singleton(){
      // ... init code
   }
   
   public Singleton getInstance(){
      return instance;
   }
   
   // autres methodes de la classe ...
}

Une variante consiste à rendre le champ static INSTANCE public et à se passer de la méthode getInstance(). Au final ça ne change pas grand-chose (le remplacement étant fait automatiquement à la compilation), c'est donc plus une affaire de goût personnel.

 

Une manière plus élégante (et plus concise) est d'utiliser un enum:

public enum Singleton{
   
   INSTANCE;
   
   private Singleton(){
      // ... init code
   }
   
   // autres methodes de la classe ...
}

C'est pas beau ça ? Difficile de faire plus simple, non ? On a toujours la création de l'instance au démarrage de la JVM mais on gagne en clarté au niveau du code et contrairement à l'approche précédente on est blindé par rapport aux petits malins qui voudraient passés par la reflection ou la sérialization pour créer une autre instance.

Maintenant pour ce qui concerne l'initialisation tardive le code est un peu plus complexe:

public class Singleton{

   private static class SingletonLoader(){
   
      private static final Singleton INSTANCE = new Singleton();
   
   }

    /** private constructor pour être sûr que personne ne pourra créer une instance **/
   private Singleton(){
      // ... init code
   }

   public Singleton getInstance(){
      return SingletonLoader.INSTANCE;
   }

   // autres methodes de la classe ...
}

Voilà la seule méthode valide pour créer un singleton avec une initialisation tardive.

Attention au code suivant (qui semble très courant - d'après ce que je voie) et qui n'est absolument pas thread safe:

public class Singleton{
   
   private static instance = null;
   
   /** private constructor pour être sûr que personne ne pourra créer une instance **/
   private Singleton(){
      // ... init code
   }
   
   public Singleton getInstance(){
      if(instance == null){
         instance = new Singleton();
      }
      return instance;
   }
   
   // autres methodes de la classe ...
}

 

Attention à ne pas abuser du design pattern Singleton. Bien souvent une classe avec des méthodes statiques est suffisantes.

Rédigé par Bliz

Publié dans #Java

Repost0
Pour être informé des derniers articles, inscrivez vous :
Commenter cet article