|
|
|
|
Le singleton |
|
|
 |
|
|
|
|
|
17 Février 2003 |
|
|
Version 1.0 |
|
|
Par Sébastien MERIC |
|
|
Remerciements : Stefan Bertholon |
|
Classe dont on veut s'assurer qu'il n'existera qu'une et une seule instance dans l'espace
et dans le temps d'un bout à l'autre du cycle de vie de l'application.
1. Synonymes 2. Synopsis 3. Structure 4. Implémentation 5. Réflexion sur l'unicité de l'instance
Ce document présente le singleton, un design pattern très connu, et si facile
à appréhender qu'il est souvent trop utilisé. Je présente celui-ci comme
premier design pattern uniquement dans un but pédagogique, pour son aspect
simple à comprendre.
1. 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 vraiement d'autres nominations mais vous entendrez peut
être parler de class à instance unique pour le désigner.
2. 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'entend par la que vous ètes certain que c'est la
même instance que vous référer quelque soit le temps écoulé entre deux appels.
3. 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'utilisont donc et appelons la méthode :
getInstance().

4. Implémentation
Voici donc l'implémentation en java :
/** 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;
}
5. 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) :
/** 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__;
}
|