I. Synonymes

Le nom du design pattern est essentiel. En effet, quand on utilise des normes afin d'être lisible par le plus grand nombre, afin d'être communicatif, il est primordial de pouvoir nommer l'outil que l'on utilise, et il est important que la terminologie soit partagée par tous. Voici donc pourquoi bien que le nom que je donne au pattern soit celui généralement partagé, il peut néanmoins apparaître d'autres nominations qu'il est bon d'exposer. Pour le singleton, il n'existe pas vraiment d'autres nominations mais vous entendrez peut être parler de class à instance unique pour le désigner.

II. Synopsis

Le singleton permet de s'assurer qu'une seule instance d'un objet donné sera instanciée pendant toute la durée de votre application. Une seule dans l'espace comme dans le temps, c'est-à-dire :

l'espace représenté par la mémoire - vous êtes certain de l'unicité de l'instance à un moment donné

le temps - vous vous assurer de l'unicité de l'instance à chaque appel. J'entends par la que vous êtes certain que c'est la même instance que vous référer quel que soit le temps écoulé entre deux appels.

III. Structure

Pour s'assurer de l'unicité de l'instance de cette classe, il faut, pour commencer, penser à mettre les constructeurs de la classe en accessibilité limitée : privée ou tout au moins protégée (attention toutefois, le constructeur protégé ne permet de s'assurer de l'unicité de l'instance et de ses héritières ! ).

Pour permettre d'accéder à cette instance unique, il est également nécessaire de penser à fournir un point d'appel, on fournira donc une méthode statique. Un standard ne de nommage existant, nous l'utilisons donc et appelons la méthode : getInstance().

Image non disponible

IV. Implémentation

Voici donc l'implémentation en java :

 
Sélectionnez
/** Exemple d'implémentation d'un singleton.<p>
  * Cet exemple ne fait rien.
  */

public class Singleton {

    /** Récupère l'instance unique de la class Singleton.<p>
    * Remarque : le constructeur est rendu inaccessible
    */
    publicstatic Singleton getInstance() {
        if (null == instance) { // Premier appel
            instance = new Singleton();
        }
        return instance;
    }

    /** Constructeur redéfini comme étant privé pour interdire
    * son appel et forcer à passer par la méthode <link
    */
    private Singleton() {
    }

    /** L'instance statique */
    private static Singleton instance;
}

V. Réflexion sur l'unicité de l'instance

Bien qu'il puisse apparaître à la lecture de ce pattern que l'instance est bien unique et ne peut pas être dupliquée, il existe un cas de figure où l'affirmation est fausse : le multithreading.

En effet, dans le cas de multithreading, l'instance présentée sous cette forme sera multiple si deux threads essayent d'accéder ensemble à la méthode getInstance().

La parade pourrait alors être (je suis ouvert à d'autres propositions bien entendu) :

 
Sélectionnez
/** Exemple d'implémentation d'un singleton dans le cas du multithreading.<p>
  * Cet exemple ne fait rien.
  */

public class Singleton {

    /** Récupère l'instance unique de la class Singleton.<p>
    * Remarque : le constructeur est rendu inaccessible
    */
    public static Singleton getInstance() {
        if (null == instance) { // Premier appel
            synchronized(objetSynchrone__) {
                if (null == instance) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }

    /** Constructeur redéfini comme étant privé pour interdire
    * son appel et forcer à passer par la méthode <link
    */
    private Singleton() {
    }

    /** L'instance statique */
    private static Singleton instance;
    /** objet pour la synchronisation. <p>
     * j'ajoute deux "soulignés" (__) au nom de l'attribut car il n'a
     * qu'un intérêt purement technique.
     */
    private static Object objetSynchrone__;
}