[review]Design Pattern:Singleton
Singleton
Singleton is simple, i think most of coders have used it in our system. Which guarantees that a class only has one instance, and provides a global entry to the client to access it.
How do we make this happen, a global entry. and we should prohibit any possibilities to initialize it. Singleton made it with holding a instance of itself and a providing a priviate constructor to prevent it from being initialized at the outside of the class itself.
When we use this pattern
as i said above, only one instance is allowed in all the system.
Roles in this pattern
Singleton:desinged to hold a instance of itself and provide a entry to access it by the client. also responsible for creating only instance.
a small demo in C# for the singleton:
namespace Singleton
{
class Program
{
static void Main(string[] args)
{
Singleton singleton = Singleton.GetInstance();
}
}
public class Singleton
{
private static Singleton instance;
private Singleton() { }
public static Singleton GetInstance()
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
The above code makes the initial prototype of the singleton pattern, but it has some drawbacks. you can find it has the thread security issue. if there are two thread accessing the GetInstance() entry, there are possible that we create two instance of the single. it is incredible violating the only one instance principle of this pattern. and which also wastes the resource of the system. we can inprove it by the lock mechanism of the C#.
Lock mechanism provides the way that makes the code in the lock block be accessed by only one thread and the another thread should wait until the previous thread exit. So it provides the thread security.
See below with a upgraded code:
namespace Singleton
{
class Program
{
static void Main(string[] args)
{
Singleton singleton = Singleton.GetInstance();
}
}
public class Singleton
{
private static readonly object syncRoot = new object();
private static Singleton instance;
private Singleton() { }
public static Singleton GetInstance()
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
}
We can also use the static mechanism to simplify the above code. as an inherent feature, the static member is thread safe. the above can be simplified as below:
namespace Singleton
{
class Program
{
static void Main(string[] args)
{
Singleton singleton = Singleton.GetInstance();
}
}
public class Singleton
{
private static Singleton instance=new Singleton();
private Singleton() { }
public static Singleton GetInstance()
{
return instance;
}
}
}
The difference between the code with lock and the code with the usage of the static is when to create the instance, as we know, the static member is created when the type is accessed at the first time.
The instance with the lock is created when we need to create the instance at the first time, but the instance with the static way is created when the Singleton itself is accessed at the first time.
Software design is full of trade-offs, there is no hard way for which one of them is better. we got to consider the situation before our decision.