19
juin
07

Design pattern de création “Singleton”

Le singleton est un design pattern de création et est l’un des plus utilisés!

Le but de ce design pattern est d’assurer au développeur une seule et unique instance d’une classe au sein de l’application. Ce qui signifie que lorsque l’on accède à une instance d’une classe équipée d’un singleton, on accède toujours à la même instance.

L’intérêt est de créer une instance commune car l’on a aucune utilité à venir dupliquer des instances faisant au final un travail commun et répétitif. On se situe en fait dans une approche de classe à instance unique. Mais comment est-ce possible de faire cela ? Tout simplement en jouant avec un constructeur, une méthode et une variable d’instance.

La première chose à faire est de venir déclarer une variable d’instance:

private static MyClass theSingleInstance;

Cette variable est déclarée private et static et elle va référencer l’instance unique que nous désirons. Ensuite il est nécessaire d’avoir un constructeur:

private MyClass() {}

Ce constructeur ne peut pas être accédé depuis l’extérieur de la classe étant donné qu’il est déclaré comme private. Ici le constructeur est vide mais la construction de l’instance peut être plus poussée. Et finalement, il manque une méthode qui est finalement le coeur du singleton:

public synchronized static MyClass getInstance() {
  if (null == instance) {
    instance = new Singleton();
  }
  return instance;
}


Dans le cas où l’instance est null, la méthode créé une nouvelle instance mais dans le cas contraire elle rend l’instance référencé par la variable d’instance. Cette méthode est bien entendu public afin d’être accessible à toutes les classes et static étant donné qu’elle est indépendante de toute instance.

Tout cela nous donne le code complet suivant:

public class MyClass {

  private static MyClass theSingleInstance;

  private MyClass() {}

  public synchronized static MyClass getInstance() {
    if (null == instance) {
      instance = new Singleton();
    }
    return instance;
  }
}

Certains l’auront peut-être remarqué mais une autre solution est possible. C’est d’avoir une méthode getInstance() retournant dans tous les cas la variable theSingleInstance sans devoir tester si elle est null ou non. Voici ce code:

public class MyClass {

  private static MyClass theSingleInstance = new MyClass();

  private MyClass() {}

  public static MyClass getInstance() {
    return instance;
  }
}

Le travail est alors fait lors du chargement de la classe qui vient directement créer une instance de la classe sans devoir passer par la méthode getInstance, cette dernière ne faisant que retourner l’instance unique.

Au développeur à estimer si l’instance est nécessaire dés le début, la deuxième solution est préférable, ou l’autre cas si il se peut que l’instance ne soit pas obligatoirement utilisée, la première solution est préférable.

Liens externes


6 Réponses vers “Design pattern de création “Singleton””


  1. 1 SingletonHater
    23 juin 2007 à 21:05

    super ton singleton … il est pas thread safe … et quel pattern inutile, intestable, qui introduit beaucoup de couplage dans le code et qui rend les tests unitaires … pas tres unitaires … bref, a eviter … Le singleton fait plutot partie de ce qu’on appelle les “anti-patterns” .

  2. 2 alex
    24 juin 2007 à 10:43

    Je trouve que l’utilisation d’un singleton est un code très propre même si ce dernier est considéré comme un anti-pattern par excellence. Alors le singleton, pattern ou anti-pattern ? Je crois que c’est une question dont la réponse est assez subjective ou du moins du cas par cas.

    Ce que SingletonHater veut dire en premier lieu, c’est que le pattern Singleton n’est pas quelque chose de facilement testable. Pour qu’une classe par exemple soit testable, il faut qu’elle soit le plus indépendant possible des autres classes. Ce qui introduit en deuxième lieu la notion de “loose coupling”. Une classe est considérée comme “loosely-coupled” si elle n’est pas dépendante d’autres classes tandis que une classe est considérée comme “tightly-coupled” si elle est dépendante d’autres classes.

    Par conséquent, le singleton, tout en apportant un aspect important, qui est l’unicité de l’instance, il ne respecte pas certains principes comme le “loose coupling”.

  3. 3 ZeArnal
    1 août 2007 à 14:01

    SingletonHater : Peux-tu développer quand tu parles de “thread safe” ?

    J’ai un problème qui ressemblerait à l’utilisation de ce singleton et d’un autre coté l’augementation anormale de thread.

  4. 4 Bab
    18 décembre 2007 à 21:37

    Et puis ce serai sympa que le code soit cohérent, vu qu’il ne peut pas compiler.
    Correction :
    public class MyClass {

    private static MyClass theSingleInstance;

    private MyClass() {}

    public synchronized static MyClass getInstance() {
    if (null == theSingleInstance) {
    theSingleInstance = new MyClass();
    }
    return theSingleInstance;
    }
    }

  5. 5 Alexis
    19 décembre 2007 à 9:43

    Bien vu, le nom de la variable contenant l’instance n’était pas correct ;-)

  6. 6 foreigner6
    9 mars 2008 à 16:28

    Salut à tous

    Très intéressante discussion !

    Concernant le problème Thread Safe évoqué, effectivement je me demande qu’est ce qui nous garanti que la solution 2 soit Thread Safe ? La solution 1 utilise un “synchronized”, elle est donc bien Thread Safe mais l’autre ?

    J’ai été amené à utiliser in Singleton sent m’en rendre compte pour faciliter grandement mon code et sa lisibilité mais c’est vrai que j’ai qq doutes sur l’écologie de tout ca… Ca pourrait être intéressant de statuer la dessus SingletonHater non ?

    J’utilise ce Singleton comme une sorte de base de donnée, une macro-variable globale que j’utilise comme référence dans mes classes plutôt que de le passer en paramètres à toutes les méthodes qui en on besoin.

    Je m’explique : Ce macro-objet représente mon système modélisé qui contient tous les paramètres nécessaires. Certaines des propriétés de cet objet sont bien sur liées entre elle comme une sorte de base de donnée.

    L’objectif de ce macro objet est de ne pas stocker dans mes classes des objets mais des références aux objets de ce macro-objet afin de limiter l’occupation mémoire. Donc si une classe Voiture contient une liste d’options et que ces options peuvent se retrouver pour plusieurs voitures, j’aurai dans mon macro-objet une liste de voiture et une liste d’options. L’objet “Renault Scenic” renverra un objet Option issu du macro-objet qui sera éventuellement le même que pour l’objet “Renault Laguna”. Ceci permet d’éviter de surcharger la mémoire d’une part et d’autre part de centraliser les modifications qui pourraient s’effectuer sur l’option elle même sans avoir à modifier les objets dépendant.

    Qu’est ce que vous en pensez ?


Laisser un commentaire




BIENVENUE

Java Village fait son bout de chemin depuis maintenant environ un an, et l'équipe en profite au passage, au nom des différents contributeurs, de vous remercier de vos visites mais aussi de vos participations. A bientôt en espérant vous voir venir nous lire de plus en plus souvent!

BLOG STATS

  • 74,614 hits

STATISTIQUES

Vous êtes à présent environ 1500 visiteurs par mois à venir visiter Java Village, ce qui représente presque le double de visiteurs par rapport aux résultats affichés il y a un trimestre. Merci à tous.

Livre du moment…

SCJP

a

Partenaires