Bien implémenter son singleton

Java — Tags :, , , — admin @ 11:54

Lorsque plusieurs membres d’un programme vont utiliser les mêmes données, on se retrouve confronté au choix entre le singleton et la classe statique. Ce choix est assez important, et dépend entièrement de la visibilité de ces données. Il sera parfois plus judicieux d’utiliser une classe statique qu’un singleton. Par exemple, en programmant un jeu de tennis en C# (que je n’ai pas encore complètement terminé d’ailleurs…), j’avais besoin d’accéder souvent au calendrier ATP. La visibilité de ce calendrier était pratiquement globale, beaucoup de classes devaient y avoir accès et il était plus facile d’en faire une classe statique avec ses méthodes statiques… Dans d’autres cas, le singleton était plus approprié. Il n’est pas limité en accès aux membres statiques, il est sérializable, etc…

Récemment, en révisant du code sur un projet au boulot, je suis tombé sur des mauvaises implémentations de singletons de ce type :

  1. public class SinglePart {
  2.      private static SinglePart oPart = null;
  3.  
  4.      public static SinglePart getSinglePart() {
  5.          if (oPart == null){
  6.              oPart = new SinglePart();
  7.          }
  8.          return oPart;
  9.      }
  10.  }

La classe fonctionnait bien, puisque le programmeur avait fait attention à ne l’instancier qu’une seule fois. En fait, il y a 2 erreurs avec cette implémentation :

- Il manque un constructeur privé pour remplacer le constructeur public et donc éviter une autre instanciation via ce dernier.
- Rien n’assure que le singleton ne soit créé deux fois en même temps par deux threads séparés.

La solution consiste donc à ne pas oublier le constructeur privé, ainsi que l’utilisation du mot clef synchronized :

  1. public class SinglePart {
  2.      private static SinglePart oPart = null;
  3.  
  4.      // constructeur privé
  5.      private SinglePart() {}
  6.  
  7.      public synchronized static SinglePart getSinglePart() {
  8.          if (oPart == null){
  9.              oPart = new SinglePart();
  10.          }
  11.          return oPart;
  12.      }
  13.  }

0 Comments »

Pas encore de commentaire.

Flux RSS des commentaires de cet article. TrackBack URI

Laisser un commentaire

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.
(c) 2012 Random namespace | powered by WordPress with Barecity