Design pattern Singleton avec .Net (VB.Net et C#)
Date de publication : 10/07/2007
Par
Ronald VASSEUR (autres articles)

Les design patterns sont nombreux et plus ou moins connus, au cours de cet
article je vais vous présenter le plus connu et populaire, il s'agît du Singleton.
Ce pattern à pour but de contrôler et de limiter à une ou quelques unes le nombre
d'instances existantes pour une classe donnée. Voyons sans plus tarder comment
implémenter ce pattern en .Net (Visual Basic 2005 et C# 2.0).
Introduction
1. Présentation du pattern singleton
2. Utiliser le pattern singleton avec .Net
Conclusion
Introduction
Tout d'abord je pense qu'il est utile de préciser ce qu'est un pattern,
il s'agit en fait d'un modèle utilisé en génie logiciel. Un pattern est
donc une manière de procéder en programmation, il définit comment
doivent s'articuler certains éléments d'un bout de code ou d'une
application. Il existe des dizaines de patterns couvrant de très
nombreux domaines du génie logiciel. Ils sont le plus souvent crées
grâce à des retours d'expérience, et des moyens de procéder largement
éprouvés et reconnus, ils peuvent s'apparenter aux "bonnes manières
de faire". Les design patterns sont un ensemble de patterns
s'intéressant à la conception de logiciel, comment ils doivent être
conçus et quels modèles ils doivent reprendre. Dans cet article nous
allons étudier un pattern très connu et très utilisé, il s'agit du
Singleton. Il est tellement utilisé que peut être vous l'avez déjà
utilisé sans même le savoir.
1. Présentation du pattern singleton
Le Singleton est un modèle de conception. Son but est relativement
simple, il doit permettre de limiter le nombre d'instance d'une
classe à une ou quelques unes. En effet, dans de nombreuses occasions
nous devons être sûrs qu'il n'existe pas plus d'une seule instance
pour une classe donnée, cela peut être par exemple le cas d'un objet
gérant une connexion à une base de données, ou encore d'un objet écrivant
dans un fichier de log... Le Singleton, par un principe simple qui va nous
permettre de s'assurer qu'il n'existe qu'une seule instance d'une
classe donnée, en fait c'est le Singleton lui-même qui effectue cet
autocontrôle et va agir en fonction de la situation. Ainsi, si
aucune instance n'existe alors une instance sera créée, et, si une
instance existe déjà alors, il nous retournera une référence vers
cette instance déjà existante.
La caractéristique majeure d'un Singleton est que le constructeur
de cette classe est privé (Private en VB .Net), il n'est donc pas
accessible comme doit normalement l'être le constructeur d'une classe.
En effet, dans l'ordre normal des choses un constructeur doit être
public, pour qu'on puisse instancier notre classe en appelant sa
méthode New().
Puisque le constructeur n'est pas Public, il va falloir avoir au
moins une méthode publique pour que l'on puisse utiliser notre
Singleton. C'est cette méthode publique qui concrètement va vérifier
si une instance existe déjà ou non. Cette méthode, sera le seul et
unique moyen pour un développeur, et donc une application, de créer
une instance de cette classe implémentant le design pattern Singleton.
Un autre détail qui a son importance c'est le fait que l'on doive déclarer
une variable locale qui aura pour rôle de stocker la référence à
l'instance unique de notre Singleton. Regardons maintenant comment
concrètement implémenter le pattern Singleton avec Visual Basic
2005 et C# 2.0.
2. Utiliser le pattern singleton avec .Net
Voici un exemple de classe implémentant le pattern Singleton :
| Implémentation du design pattern Singleton en VB.Net |
Option Explicit On
Option Strict On
Public Class MonSingleton
Private Shared instance As MonSingleton = Nothing
Private Sub New()
End Sub
Public Shared Function GetInstance() As MonSingleton
If instance Is Nothing Then
instance = New MonSingleton
End If
Return instance
End Function
End Class
|
| Implémentation du design pattern Singleton en C# |
public class MonSingleton
{
private static MonSingleton instance = null;
private MonSingleton()
{
}
public static MonSingleton GetInstance()
{
if (instance == null)
{
instance = new MonSingleton();
}
return instance;
}
}
|
L'implémentation ci-dessus du Pattern Singleton est correcte mais présente un
petit défaut, en effet, elle n'est pas thread-safe, c'est à dire que
rien n'empêche plusieurs thread d'utiliser une instance de notre
Singleton en même temps. Pour contourner ce problème nous allons
utiliser un mot clé Synlock en VB.Net et Lock en C# pour faire en
sorte qu'une telle chose ne soit pas possible. Voyons sans plus
tarder comment appliquer cela dans le code :
| Implémentation du design pattern Singleton thread-safe en VB.Net |
Option Explicit On
Option Strict On
Public Class MonSingleton
Private Shared instance As MonSingleton = Nothing
Private Shared ReadOnly mylock As New Object()
Private Sub New()
End Sub
Public Shared Function GetInstance() As MonSingleton
Synclock(mylock)
If instance Is Nothing Then
instance = New MonSingleton
End If
Return instance
End Synclock
End Function
End Class
|
| Implémentation du design pattern Singleton thread-safe en C# |
public class MonSingleton
{
private static MonSingleton instance = null;
private static readonly object mylock = new object();
private MonSingleton()
{
}
public static MonSingleton GetInstance()
{
lock ((mylock)) {
if (instance == null)
{
instance = new MonSingleton();
}
return instance;
}
}
}
|
Désormais notre Singleton est réellement thread-safe et il est
impossible, même à des threads différents, de créer plusieurs instances
de cette classe, il y a une vérification lors de l'instanciation
et un verrou en mémoire sur l'objet.
 |
Remarque : attention, Synlock/Lock est certes efficace pour rendre notre
Singleton thread-safe mais il faut garder à l'esprit que cette manière de
procéder peut suivant les conditions être couteuse en termes de performances,
comme d'habitude en développement il faudra donc évaluer le pour et le
contre. Mais, a mon avis, cette légère perte de performance vaut largement
la sécurité et la robustesse que l'on apporte a notre Singleton.
|
Maintenant que notre Singleton est implémenté, voyons comment le
démontrer. Pour cela, voici le code d'une petite application
console qui va vérifier que tous les objets de types MonSingleton
correspondent bien à une seule et même instance. Pour cela nous
allons utiliser la méthode Equals() que chaque objet .Net implémente
et qui permet de comparer l'égalité ou non de deux objets.
| Application console de test du Singleton en VB.Net |
Option Explicit On
Option Strict On
Imports SingletonDeveloppez
Module Module1
Sub Main()
Dim objet1 As MonSingleton = Nothing
objet1 = MonSingleton.GetInstance()
Dim objet2 As MonSingleton = Nothing
objet2 = MonSingleton.GetInstance()
If objet1.Equals(objet2) Then
Console.WriteLine("Les deux instances sont identiques.")
End If
Console.ReadLine()
End Sub
End Module
|
| Application console de test du Singleton en C# |
using SingletonDeveloppez;
class Module1
{
public void Main()
{
MonSingleton objet1 = null;
objet1 = MonSingleton.GetInstance();
MonSingleton objet2 = null;
objet2 = MonSingleton.GetInstance();
if (objet1.Equals(objet2))
{
Console.WriteLine("Les deux instances sont identiques.");
}
Console.ReadLine();
}
}
|
Conclusion
Nous avons vu dans cet article une manière d'implémenter simplement
le design pattern Singleton avec VB.Net et en C#. En suivant ce
pattern vous voyez à quel point il est simple de contrôler le nombre
d'instances qui peuvent exister au même moment pour une classe donnée.
Toute l'astuce de ce pattern est que le contrôle du nombre d'instance
s'effectue au sein même de la classe et non par un code annexe qui le
rendrait peu fiable. Un autre avantage qu'apporte ce pattern est le
fait que la modification du processus d'instanciation de la classe
n'aura pas d'impact sur le reste de l'application et du code existant,
en effet l'instanciation de la classe est entièrement gérée par la
classe elle-même grâce au constructeur Private et à la méthode
GetInstance().
Un grand merci à AGM26 pour la relecture de cet article, ainsi qu'à l'équipe Dotnet pour son aide.


Copyright © 2007 Ronald Vasseur. Aucune reproduction, même partielle, ne peut être faite
de ce site et de l'ensemble de son contenu : textes, documents, images, etc
sans l'autorisation expresse de l'auteur.
Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
Cette page est déposée à la
SACD.