# Patrons de conception/Singleton

* Introduction
* Patrons du « Gang of Four »
** Patrons de création
*** Singleton
*** Prototype
*** Fabrique
*** Fabrique abstraite
*** Monteur
** Patrons de structure
*** Pont
*** Façade
*** Adaptateur
*** Objet composite
*** Proxy
*** Poids-mouche
*** Décorateur
** Patrons de comportement
*** Chaîne de responsabilité
*** Commande
*** Interpréteur
*** Itérateur
*** Médiateur
*** Mémento
*** Observateur
*** État
*** Stratégie
*** Patron de méthode
*** Visiteur
* Patrons GRASP
** Expert en information
** Créateur
** Faible couplage
** Forte cohésion
** Contrôleur
** Polymorphisme
** Fabrication pure
** Indirection
** Protection
* Patrons d'entreprise
** Logique du domaine
*** Script de transaction
*** Modèle du domaine
*** Module de table
*** Couche de service
** Architecture de source de données
*** Passerelle de table de données
*** Passerelle de ligne de données
*** Enregistrement actif
*** Gestion de données
** Comportement objet-relationnel
*** Unité de travail
*** Carte d'identité
*** Chargement différé
** Structure objet-relationnel
** Association méta-données objet-relationnel
** Présentation web
** Distribution
** Concurrence locale (hors-ligne)
** État de session (Session State Patterns)
** Patrons de base
*** Passerelle (Gateway)
*** Mapper
*** Type de base pour la couche
*** Interface séparée
*** Registre
*** Plugin
*** Objet valeur
*** Monnaie
*** Cas spécial
*** Service de substitution
*** Ensemble d'enregistrements
* Autres patrons
** Type fantôme
** Double-dispatch
** Post-Redirect-Get
** Map-Reduce
** Évaluation retardée
** Copie sur modification
** Injection de dépendance
** Inversion de contrôle
** Modèle-Vue-Contrôleur
** Modèle-Vue-Présentateur
** Écart de génération
** Objet nul
** Objets réutilisables
** Outbox
** Feature toggles
* Bibliographie et liens
* Introduction
* Patrons du « Gang of Four »
** Patrons de création
*** Singleton
*** Prototype
*** Fabrique
*** Fabrique abstraite
*** Monteur
** Patrons de structure
*** Pont
*** Façade
*** Adaptateur
*** Objet composite
*** Proxy
*** Poids-mouche
*** Décorateur
** Patrons de comportement
*** Chaîne de responsabilité
*** Commande
*** Interpréteur
*** Itérateur
*** Médiateur
*** Mémento
*** Observateur
*** État
*** Stratégie
*** Patron de méthode
*** Visiteur
* Patrons GRASP
** Expert en information
** Créateur
** Faible couplage
** Forte cohésion
** Contrôleur
** Polymorphisme
** Fabrication pure
** Indirection
** Protection
* Patrons d'entreprise
** Logique du domaine
*** Script de transaction
*** Modèle du domaine
*** Module de table
*** Couche de service
** Architecture de source de données
*** Passerelle de table de données
*** Passerelle de ligne de données
*** Enregistrement actif
*** Gestion de données
** Comportement objet-relationnel
*** Unité de travail
*** Carte d'identité
*** Chargement différé
** Structure objet-relationnel
** Association méta-données objet-relationnel
** Présentation web
** Distribution
** Concurrence locale (hors-ligne)
** État de session (Session State Patterns)
** Patrons de base
*** Passerelle (Gateway)
*** Mapper
*** Type de base pour la couche
*** Interface séparée
*** Registre
*** Plugin
*** Objet valeur
*** Monnaie
*** Cas spécial
*** Service de substitution
*** Ensemble d'enregistrements
* Autres patrons
** Type fantôme
** Double-dispatch
** Post-Redirect-Get
** Map-Reduce
** Évaluation retardée
** Copie sur modification
** Injection de dépendance
** Inversion de contrôle
** Modèle-Vue-Contrôleur
** Modèle-Vue-Présentateur
** Écart de génération
** Objet nul
** Objets réutilisables
** Outbox
** Feature toggles
* Bibliographie et liens
[ Modifier le sommaire ]
Le singleton est un patron de conception dont l'objet est de restreindre l'instanciation d'une classe à un seul objet (ou bien à quelques objets seulement). Il est utilisé lorsque l'on a besoin d'exactement un objet pour coordonner des opérations dans un système. Le modèle est parfois utilisé pour son efficacité, lorsque le système est plus rapide ou occupe moins de mémoire avec peu d'objets qu'avec beaucoup d'objets similaires.
On implémente le singleton en écrivant une classe contenant une méthode qui crée une instance uniquement s'il n'en existe pas encore. Sinon elle renvoie une référence vers l'objet qui existe déjà. Dans beaucoup de langages de type objet, il faudra veiller à ce que le constructeur de la classe soit privé ou bien protégé, afin de s'assurer que la classe ne puisse être instanciée autrement que par la méthode de création contrôlée.
Le singleton doit être implémenté avec précaution dans les applications multi-thread. Si deux processus légers exécutent en même temps la méthode de création alors que l'objet unique n'existe pas encore, il faut absolument s'assurer qu'un seul créera l'objet, et que l'autre obtiendra une référence vers ce nouvel objet.
La solution classique à ce problème consiste à utiliser l'exclusion mutuelle pour indiquer que l'objet est en cours d'instanciation.
Dans un langage à base de prototypes, où sont utilisés des objets mais pas des classes, un singleton désigne seulement un objet qui n'a pas de copies, et qui n'est pas utilisé comme prototype pour d'autres objets.

## Diagramme de classes UML

La figure ci-dessous donne le diagramme de classes UML du patron de conception Singleton.

## Implémentations
### Java

Voici une solution écrite en Java (il faut écrire un code similaire pour chaque classe-singleton) :
Une solution variante existe cependant. Elle consiste à alléger le travail de la méthode getInstance en déplaçant la création de l'instance unique au niveau de la déclaration de la variable référant l'instance unique :
À noter que la première implémentation est plus lente, étant donné que la méthode getInstance est synchronisée, les processus doivent faire la queue alors que le synchronized n'est utile qu'au premier appel, après l'instanciation, il n'y a pas d'erreur possible, toutefois il n'y a pas d'autres possibilités : faire un verrouillage au niveau de l'objet dans la méthode ne suffit pas.
La dernière implémentation a une faille, il est possible, en sérialisant puis en désérialisant la classe d'obtenir une seconde instance. Une troisième implémentation permet de pallier ce problème, le singleton est l'unique élément d'une énumération.

### C++

Voici une implémentation possible en C++, connue sous le nom de "singleton de Meyers". Le singleton est un objet static et local. Attention : cette solution n'est pas sûre dans un contexte multi-thread ; elle sert plutôt à donner une idée du fonctionnement d'un singleton qu'à être réellement utilisée dans un grand projet logiciel. Aucun constructeur ou destructeur ne doit être public dans les classes qui héritent du singleton.

### Python
#### Implémentation simple

Les deux variables référencent ici la même instance. Cette solution ne nécessite pas de méthode spécifique pour accéder à l'instance de classe (comparativement à d'autres langages, où il est d'usage d'implémenter une méthode getInstance, par exemple).

#### Considérations "avancées"

D'après le développeur Python Alex Martelli, le patron de conception Singleton a un nom élégant mais trompeur, car il met l'accent sur l'identité plutôt que sur l'état de l'objet. D'où l'apparition d'un patron alternatif, appelé Borg, pour lequel toutes les instances partagent le même état. Il est généralement accepté par la communauté de développeurs Python que le partage d'état entre instances est plus élégant que la mise en cache de la création d'instances identiques lors de l'initialisation de la classe.
L'implémentation de cet état partagé est quasiment transparente en Python :
L'implémentation ci-dessus peut être améliorée en tirant partie du nouveau type de classe de Python, ne nécessitant ainsi qu'une seule instance :
* La méthode __init__ est exécutée pour chaque appel à Singleton.
* Afin de permettre à une classe d'hériter d'un Singleton, la variable de classe instance devrait être un dictionnaire Python appartenant explicitement à la classe Singleton, comme illustré ci-dessous :

### Ruby

Le patron Singleton existe dans la librairie standard du langage Ruby. C'est un mixin qu'il suffit d'inclure dans la classe qui doit être un singleton.
Ce script affiche "foo".

### PHP 5

Voici une solution écrite en PHP :

#### Avant PHP 5.3 : Difficultés liées à l'héritage d'une classe Singleton

Il faut noter qu'avant PHP 5.3, il n'est pas possible d'hériter une classe de type Singleton. En effet, l'accesseur self:: se réfère toujours à la classe dans laquelle il est écrit. L'exemple ci-dessous illustre ce problème.
Ce problème ne peut être résolu qu'en dupliquant la méthode getInstance dans la classe héritée.

#### Depuis PHP 5.3 : le mot-clé static et le Late Static Bindings

Avec PHP 5.3, l'apparition du Late Static Bindings sous la forme d'un accesseur static:: semblable à self:: résout ce problème. En effet, l'accesseur static:: se réfère à la classe dans laquelle il est appelé. Il peut donc être hérité. C'est pourquoi l'on parle de Late Static Bindings (Résolution statique à la volée), par opposition à une résolution statique au moment de la compilation du script.

### Perl

Pour les versions de Perl à partir de 5.10, une variable d'état fait l'affaire.
Pour les versions plus anciennes, c'est une fermeture (closure en anglais) qui fera l'affaire.
Si le module Moose est utilisé, il y a l'extension MooseX::Singleton

## Voir aussi

* Objet nul pouvant utiliser le patron singleton.

## Notes et références

* ↑ anglais Voir l'article « The dreaded double checked locking idiom in Java ».
* ↑ Voir l'article « The Perfect Singleton », par Marek Piechut sur son blog Development world stories
* ↑ anglais Alex Martelli, « Singleton? We don't need no stinkin' singleton: the Borg design pattern », ASPN Python Cookbook (consulté le 7 septembre 2006)
* ↑ anglais « New-style classes », Python documentation

## Liens externes
### Divers

* français Explication du Singleton et de ses variantes en Java par Java Village
* français Explication du Singleton en C++