Il pattern singleton è forse uno dei più conosciuti e consiste nel limitare una classe ad una sola istanza e che questa sia accessibile pubblicamente.
Il modo più semplice per implementare un singleton è quello di definire una classe in questo modo:
// Singleton in C# 1.x
public sealed class MyClass // sealed evita che sia derivabile
{
private MyClass {} // costruttore privato per evitare che la classe sia istanziabile
public static int MyMethod(int x, int y) {return x+y;} // Metodo statico
}
Dove posso usare la forma MyClass.MyMethod(2, 3);
In C# 2.0 la forma è più elegante ma pressochè identica:
public static class MyClass // static sulla classe obbliga tutti i suoi metodi ad essere statici
{
public static int MyMethod(int x, int y) {return x+y;} // Metodo statico
}
Ma se volessimo un singleton che obbedisca a un contratto stabilito da interfacce? Per una serie di ottimi motivi ben descritti su msdn e in vari blog sulla rete non è possibile definire delle interfacce 'statiche'.
La soluzione è banale e già pluriusata all'epoca COM non troppo lontana ma ormai con dotnet siamo abituati troppo bene e così ecco una delle possibili implementazioni alternative.
// Singleton implementato senza static (C# 1.x)
public sealed class MyClass
{
private static MyClass _mySelf = null;
public static MyClass GetInstance()
{
if(_mySelf == null)
_mySelf = new MyClass();
return _mySelf;
}
private MyClass() {}
}
Con questa implementazione viene creata l'unica istanza grazie al factory pattern e successivamente restituita sempre la stessa istanza. Da notare che in questo modo, contrariamente alla soluzione con static, è possibile implementare con poche righe aggiuntive del codice che butti via l'istanza. Così facendo non ci sarà più neppure l'unica istanza disponibile che verrà riallocata appena richiesta la volta successiva.