Intent:: Singleton Pattern - Creational
Intent:: Singleton Pattern - Creational
Intent:
To create exactly one object of a class, and to provide global point of access to it.
Motivation:
While developing applications, we will face frequent situations where there is a need
to create exactly one instance of a class. For example, in a GUI application there is a
requirement that there should be only one active instance of the application’s user
interface.
No other instance of the user interface of the application should be created by the
user. Another example is the requirement to maintain only one print spooler.
We need to allow the class to have exactly one instance and to allow a global point
of access to it. How to do it? A global variable might allow you to provide global
access to the object but it does not restrict you from creating multiple objects.
A better solution is to allow the class to take the responsibility of creating only one
object and to provide a global point of access to it. This is what the singleton pattern
does. The singleton pattern allows the class to create only one instance, allow other
external objects to access that instance and does not allow the constructor to be
invoked directly each time.
Applicability:
Singleton Pattern can be used when:
1. There must be exactly one instance of a class and to provide a global point of
access to it.
2. When the sole instance should be extensible by sub classing, and clients
should be able to use the extended instance without modifying its code.
• Logger classes
• Configuration classes
• Accessing resources in shared mode
• Factories implemented as Singletons
Structure:
Participants:
Consists of a “Singleton” class with the following members:
Collaborations:
Clients access the singleton instance solely through the singleton’s class operation.
Consequences:
Implementation:
The Singleton pattern defines a getInstace() class method which creates the new
instance and is responsible for maintaining a single instance of the class.
It also provides global access to the clients as it will be a public method. The
implementation code will be as follows:
?
1
2
class Singleton
3 {
4 private static Singleton instance;
5 private Singleton()
6 {
...
7 }
8 public static synchronized Singleton getInstance()
9 {
10 if (instance == null)
11 instance = new Singleton();
return instance;
12 }
13 ...
14 public void doOperation()
15 {
...
16
}
17 }
18
19
We can see from the above code that the getInstance() method ensures that only
one instance of the class is created. The constructor must not be accessible from
outside the class. So, it is made private
The only way for instantiating the class is through getInstance() method. It is also
responsible for providing a global point of access to the instance as shown below:
Singleton.getInstance().doSomething();
?
1 //Lazy instantiation using double locking mechanism.
class Singleton
2
{
3 private static Singleton instance;
4 private Singleton()
5 {
6 System.out.println("Singleton(): Initializing Instance");
}
7 public static Singleton getInstance()
8 {
9 if (instance == null)
10 {
11 synchronized(Singleton.class)
{
12 if (instance == null)
13 {
14 System.out.println("getInstance(): First time getInstance w
15 instance = new Singleton();
}
16 }
17 }
18 return instance;
19 }
20 public void doSomething()
{
21 System.out.println("doSomething(): Singleton does something!");
22 }
23 }
This double checking method is not supported in previous versions before java 5.
For a universal solution, we can use the nested class approach.
In this Singleton’s implementation, instance of the class is created when the class is
loaded by the class loader as the data member will be marked as static.
1) If the constructor is made protected, another class in the same package can
access it to create a new object. This defeats the purpose of a Singleton.
2) In the derived class or subclass, all the calls to the getInstance() method i.e.,
Singleton.getInstance() should be replaced with NewSingleton.getInstance().
Serialization:
If the Singleton class implements the java.io.Serializable interface, when a singleton
is serialized and then deserialized more than once, there will be multiple instances of
Singleton created.
In order to avoid this the readResolve method should be implemented. The code will
be as follows:
1
2 public class Singleton implements Serializable
{
3 ...
4 // This method is called immediately after an object of this class is deserial
5 // This method returns the singleton instance.
6 protected Object readResolve()
{
7 return getInstance();
8 }
9 }
10
Sample Code:
Let us take a small practical example to understand the Singleton design pattern in
more details.
Problem Statement:
Design a small ATM printing application which can generate multiple types of
statements of the transaction including Mini Statement, Detailed statement etc.
However the customer should be aware of the creation of these statements. Ensure
that the memory consumption is minimized.
Design Solution:
The above requirement can be addressed using two core Gang of four design
pattern – Factory design pattern and Singleton design pattern. In order to generate
multiple types of statements for the ATM transactions in the ATM machine we can
create a Statement Factory object which will have a factory method
of createStatements(). The createStatements will create DetailedStatement or
MiniStatement objects.
The client object will be completely unware of the object creation since it will interact
with the Factory interface only. We will also create an interface called
StatementType. This will allow further statement type objects e.g. Credit card
statement etc to be added. So the solution is scalable and extensible following the
object oriented Open/Closed design principle.
?
1
2
3 public class StatementFactory extends Factory
4 {
5 private static StatementFactory uniqueInstance;
6
private StatementFactory() {}
7
8 public static StatementFactory getUniqueInstance()
9 {
10 if (uniqueInstance == null)
11 {
12 uniqueInstance = new StatementFactory();
System.out.println("Creating a new StatementFactory instance");
13 }
14 return uniqueInstance;
15 }
16
17 public StatementType createStatements(String selection)
18 {
if (selection.equalsIgnoreCase("detailedStmt"))
19 {
20 return new DetailedStatement();
21 }
22 else if (selection.equalsIgnoreCase("miniStmt"))
{
23 return new MiniStatement();
24 }
25 throw new IllegalArgumentException("Selection doesnot exist");
26 }
27 }
28
29
Known Uses:
Related Patterns:
Other patterns like Abstract Factory, Builder and Prototype can be implemented
using the Singleton pattern.
Example Singleton classes in java API:
java.lang.Runtime
java.awt.Desktop
Non-software example:
The Singleton pattern ensures that a class has only one instance, and provides a
global point of access to that instance. The Singleton pattern is named after the
singleton set, which is defined to be a set containing one element.
The office of the President of the United States is a Singleton. The United States
Constitution specifies the means by which a president is elected, limits the term of
office, and defines the order of succession. As a result, there can be at most one
active president at any given time.
Regardless of the personal identity of the active president, the title, “The President of
the United States” is a global point of access that identifies the person in the office.