This presentation provide information about the various implementation of singleton design pattern with there pros and cons. Programming language used for implementation is c#.
2. About presentation
This presentation provide information about the various implementation of
singleton design pattern with there pros and cons.
I have tried my best to explain the various implementation in very simple language.
The programming language used for implementation is c#. But any one from
different programming background can easily understand the implementation.
3. Definition
The singleton pattern is a design pattern that restricts the Instantiation of a
class to one object.
http://en.wikipedia.org/wiki/Singleton_pattern
Singleton pattern is a creational design pattern.
4. Motivation and Intent
It's important for some classes to have exactly one instance.
e.g.
• Although there can be many printers in a system, there should be only one
printer spooler.
• There should be only one file system and one window manager.
• A digital filter will have one A/D converter.
• An accounting system will be dedicated to serving one company.
• Ensure that only one instance of a class is created.
• Provide a global point of access to the object.
6. Implementation (C#)
public class Singleton {
private static Singleton instance = null;
private Singleton() {
}
public static Singleton Instance {
get {
if (instance == null)
instance = new Singleton();
return instance;
}
}
}
When the constructor is defined as a private
method, none of the code outside the class can
create its instances. A static method inside the
class is defined to create an instance on
demand.
In this class, an instance is created only when
static field ‘Singleton.instance’ is ‘null’,
so it does not have the opportunity to get
multiple instances.
This class will works when there is only one
thread, but it has problems when there are
multiple threads in an application. Supposing
that there are two threads concurrently
reaching the if statement to check whether
instance is null. If instance is not created yet,
each thread will create one separately. It
violates the definition of the singleton pattern
when two instances are created. So let’s
explore a thread safe solution.
7. Thread Safe Implementation
public class Singleton {
private Singleton() {
}
private static readonly object syncObj = new
object();
private static Singleton instance = null;
public static Singleton Instance {
get {
lock (syncObj) {
if (instance == null)
instance = new Singleton();
}
return instance;
}
}
}
Suppose there are two threads that are both
going to create their own instances. As we
know, only one thread can get the lock at a
time. When one thread gets it, the other one
has to wait. The first thread that gets the
lock finds that instance is null, so it creates
an instance. After the first thread releases
the lock, the second thread gets it. Since the
instance was already created by the first
thread, the ‘if’ statement is ‘false’. An
instance will not be recreated again.
Therefore, it guarantees that there is one
instance even if multiple threads executing
concurrently.
This solution will work for multiple
threads, but it is not efficient as every time
‘Singleton.Instance’ get executes, it
has to get and release a lock. Operations to
get and release a lock are timeconsuming, so it should be avoided.
8. Double-Check Lock
public class Singleton {
private Singleton() {
}
private static object syncObj = new object();
private static Singleton instance = null;
public static Singleton Instance {
get {
if (instance == null) {
lock (syncObj) {
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
}
Actually a lock is needed only before the
only instance is created in order to make
sure that only one thread get the chance to
create an instance. After the instance is
created, no lock is necessary. We can
improve performance with an additional
‘if’ check before the lock.
This Singleton class locks only when
instance is null. When the instance has
been created, it is returned directly
without any locking operations. Therefore,
the time efficiency of this Singleton is
better than its earlier version. Singleton
employs two ‘if’ statements to improve
time efficiency. It is a workable solution,
but a bit complex, and it is error-prone. So
let’s explore the simpler and better
solutions.
9. Static Constructors
public class Singleton {
private Singleton() {
}
private static Singleton instance = new
Singleton();
public static Singleton Instance {
get {
return instance;
}
}
}
In this Singleton class, an instance is
created when the static field instance gets
initialized. Static fields in C# are initialized
when the static constructor is called. Since
the static constructor is called only once by
the .NET runtime, it is guaranteed that only
one instance is created even in
a
multithreading application. When the .NET
runtime reaches any code of a class for the
first time, it invokes the static constructor
automatically.
10. Lazy Instantiation
public class Singleton {
Singleton() {
}
public static Singleton Instance {
get {
return InnerClass.instance;
}
}
class InnerClass {
static InnerClass() {
}
internal static readonly Singleton instance
= new Singleton();
}
}
There
is
a
nested
private
class
‘InnerClass’ in this code of Singleton.
When the .NET runtime reaches the code of
the class ‘InnerClass’, its static
constructor is invoked automatically, which
creates an instance of type Singleton. The
class ‘InnerClass’ is used only in the
property ‘Singleton.Instance’. Since
the ‘InnerClass’ class is defined as
private (abstraction), it is inaccessible
outside of the class Singleton.
When
the
get
method
of
‘Singleton.Instance’ is invoked the
first time, it triggers execution of the static
constructor of the class ‘InnerClass’ to
create an instance of Singleton. The
instance is created only when it is
necessary, so it avoids the waste associated
with creating the instance too early.
11. Examples
• Logger Classes: Logger classes can use this pattern. Providing a global logging access point in
all the application components without being necessary to create an object each time a
logging operations is performed.
• Configuration classes: The classes which provides the configuration settings for an application
can use singleton. By implementing configuration classes as Singleton not only that we
provide a global access point, but we also keep the instance we use as a cache object. When
the class is instantiated( or when a value is read ) the singleton will keep the values in its
internal structure. If the values are read from the database or from files this avoids the
reloading the values each time the configuration parameters are used.
• Accessing resources in the shared mode: The application that work with the serial port can
use this. Let's say that there are many classes in the application, working in an multithreading environment, which needs to operate actions on the serial port. In this case a
singleton with synchronized methods could be used to be used to manage all the operations
on the serial port.
• Abstract factory, builder, prototype, facade can be implemented as singleton.