Patrons de conception/Singleton
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) :
public class Singleton
 private static Singleton INSTANCE = null;
 * La présence d'un constructeur privé supprime
 * le constructeur public par défaut.
 * Le mot-clé synchronized sur la méthode de création
 * empêche toute instanciation multiple même par
 * différents threads.
 * Retourne l'instance du singleton.
 public synchronized static Singleton getInstance()
 if (INSTANCE == null)
 INSTANCE = new Singleton();
 return INSTANCE;
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 :
public class Singleton
 /*
 * Création de l'instance au niveau de la variable.
 private static final Singleton INSTANCE = new Singleton();
 * La présence d'un constructeur privé supprime
 * le constructeur public par défaut.
 * Dans ce cas présent, le mot-clé synchronized n'est pas utile.
 * L'unique instanciation du singleton se fait avant
 * l'appel de la méthode getInstance(). Donc aucun risque d'accès concurrents.
 * Retourne l'instance du singleton.
 public static Singleton getInstance()
 return INSTANCE;
À 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.
public enum Singleton implements Serializable
 INSTANCE;
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.
template<typename T> class Singleton
 public:
 static T& Instance()
 static T theSingleInstance; // suppose que T a un constructeur par défaut
 return theSingleInstance;
 }// ceci n'est pas valide dans un contexte multi-thread
class OnlyOne : public Singleton<OnlyOne>
 // constructeurs/destructeur de OnlyOne accessibles au Singleton
 friend class Singleton<OnlyOne>; 
 //...définir ici le reste de l'interface
VB.Net.
Public Class Singleton
 ' Variable locale pour stocker une référence vers l'instance
 Private Shared instance As Singleton = Nothing
 Private Shared ReadOnly mylock As New Object()
 ' Le constructeur est Private
 Private Sub New()
 End Sub
 ' La méthode GetInstance doit être Shared
 Public Shared Function GetInstance() As Singleton
 SyncLock (mylock)
 ' Si pas d'instance existante on en crée une...
 If instance Is Nothing Then
 instance = New Singleton
 End If
 ' On retourne l'instance de Singleton
 Return instance
 End SyncLock
 End Function
End Class
C#.
public class Singleton
 private static Singleton _instance;
 static readonly object instanceLock = new object();
 private Singleton()

public static Singleton getInstance() 
 lock (instanceLock)
 if (_instance == null) 
 _instance = new Singleton();

return _instance;
ActionScript.
public class Singleton
 private static var _instance:Singleton;
 public static function getInstance():Singleton{
 if (_instance== null) {
 _instance= new Singleton();