While I personally don't like the Singleton pattern too much (it is essentially an OO mask for
Global Variables, it makes it harder to unit test etc.), I still need to use them now and then. Anyway, I saw a post by Jack Altiere about
"Using the Singleton Pattern" in .NET and since it presents an implementation that leaves a lot to be desired I decided to comment on that
For
one, he presents a solution which locks every time the singleton is
accessed (see below). The reason this is flawed is that singletons are
instantiated once, but they are accessed a lot of times and with this
implementation you pay every time you try to access the singleton
//bad implementation - don't use
//also note some initialization etc. is omitted for brevity
public static Foo Instance
{
get
{
// This lock allows thread safety.
lock (_mutex)
{
if (_instance == null)
_instance = new Foo();
return _instance;
}
}
}
There's
a better "standard" way to do that which basically means you check if
the the instance is null, lock, check again (in case more than one
thread got past the first check ) and only then instantiate (you'd also
need to mark the instance volatile in this case)
.NET has a better way to create thread safe singletons by merely using a static readonly declaration as in:
public sealed class singleton
{
public static readonly MySigleton Instance = new MySingleton()
}
This
implementation is not as lazy as the implementations above - but it is
thread safe an efficient (you can get more laziness if you use a nested
class as described
here)
But
that's not all- see, one of the problems of the Singleton pattern
(besides the ones mentioned above) is that it is also a violation of
the Single Responsibility Principle (SRP see
OO primer). You can solve this problem if you use Generics and create something like C++'s template based Singleton class:
namespace ConsoleApplication5
{
class Singleton<T> where T : new()
{
private static readonly T inst = new T();
public static T Instance
{
get { return inst; }
}
}
}
and then use that simply by doing something like Singleton<MyClass>.Instance
[update]
Eran points out that Jack's code is not only inefficient but also not thread safe (see Eran's post on the subject) - basically you need to make the instance variable volatile just like in the double check scenario
Reshef points to the "Static Gateway Pattern" as an alternate way to get the singleton effect. While we are talking about other possibilities, I should have probably mentioned that the usual way I handle situation where I need a single instance is instantiating one instance on the main/loader thread and then just using dependency injection... :)