Object Oriented Concepts
Monday, February 04, 2008
Tuesday, October 16, 2007
Monday, June 26, 2006
Singleton Pattern.
Code:
public class Singleton{
private Singleton() {}
private static Singleton instance = null;
public static Singleton getInstance() {
if (instance == null){
instance = new Singleton();
}
return instance;
}
}
public class CallSingleton {
public static void main(String[] args) {
Singleton single = Singleton.getInstance();
}
}
The intent of the pattern to ensure only one instance of a class exists and to provide a global access point.
global access point - static reference to objects.
Issue No 1 with Singleton:
Multiple threads producing multiple objects of singleton.
To overcome this issue
There are two ways in which you can ensure only one instance of singleton exists at any given time.
(1) synchronizing getInstance() method.
public static synchronized Singleton getInstance() {
if (instance == null){
instance = new Singleton();
}
return instance;
}
(2) Preferring eagerly created instance
public class Singleton{
private Singleton() {}
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
Here we are relying on JVM to create a single instance of Singleton during classloading time so that no other thread can access and create another instance.
Even the above two Singleton solutions don't guarantee that there will only ever be one object. All they can even try to guarantee is that there will be only one per classloader context. A typical application server uses a separate classloader context for each application.
In the end it all comes down to why you want a Singleton in the first place.
---------------------------------------------------------------------------------------
Issue No 2 with Singleton
(1) How global access point increases coupling
A global access point increases coupling because all classes which use the Singleton are forced to use that particular implementation. This is a particular problem if the Singleton implementation relies on the presence of other classes or resources (such as a database, or a web server).
Imagine you wanted to test the behaviour of a class which happens to reference the Singleton. Even though you may not be testing the bit of the class which uses the Singleton, you still need to include the complete, real production implementation in your tests.
Now imagine you want to test how another class uses the Singleton. You can't replace it with one which records which methods were called, or returns pre-specified values to compare against.
Real time example of Singleton - Logger.
Code:
public class Singleton{
private Singleton() {}
private static Singleton instance = null;
public static Singleton getInstance() {
if (instance == null){
instance = new Singleton();
}
return instance;
}
}
public class CallSingleton {
public static void main(String[] args) {
Singleton single = Singleton.getInstance();
}
}
The intent of the pattern to ensure only one instance of a class exists and to provide a global access point.
global access point - static reference to objects.
Issue No 1 with Singleton:
Multiple threads producing multiple objects of singleton.
To overcome this issue
There are two ways in which you can ensure only one instance of singleton exists at any given time.
(1) synchronizing getInstance() method.
public static synchronized Singleton getInstance() {
if (instance == null){
instance = new Singleton();
}
return instance;
}
(2) Preferring eagerly created instance
public class Singleton{
private Singleton() {}
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
Here we are relying on JVM to create a single instance of Singleton during classloading time so that no other thread can access and create another instance.
Even the above two Singleton solutions don't guarantee that there will only ever be one object. All they can even try to guarantee is that there will be only one per classloader context. A typical application server uses a separate classloader context for each application.
In the end it all comes down to why you want a Singleton in the first place.
---------------------------------------------------------------------------------------
Issue No 2 with Singleton
(1) How global access point increases coupling
A global access point increases coupling because all classes which use the Singleton are forced to use that particular implementation. This is a particular problem if the Singleton implementation relies on the presence of other classes or resources (such as a database, or a web server).
Imagine you wanted to test the behaviour of a class which happens to reference the Singleton. Even though you may not be testing the bit of the class which uses the Singleton, you still need to include the complete, real production implementation in your tests.
Now imagine you want to test how another class uses the Singleton. You can't replace it with one which records which methods were called, or returns pre-specified values to compare against.
Real time example of Singleton - Logger.