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 dé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().
IV. 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;
}
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) :
/** 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__;
}