Java-Singleton-Design-Pattern
Design patterns represent solutions to problems that arise when developing software within a particular context.
Singleton design pattern Ensure that a class only has one instance and provide a global point of access to it. Singleton pattern is used in single -threaded applications. There are many number of cases in programming where you need to make sure that there can be one and only one instance of a class. For example, your system can have only one window manager or print spooler, or a single point of access to a database engine.
There are many ways to make a class that can have only one instance. The following are the approaches
§ Embed a static variable inside the class that we set on the first instance and check for each time we enter the constructor. Static variable is a class variable.
static boolean instance_flag = false;
Here the problem is how to find out weather creating an instances was successful or not, because constructors do not return values. One way would be to call a method that checks for the success of creation and which simply returns some value derived from the static variable. This is inelegant and prone to error.
Best is to create a class that throws an exception when it creates a more than one object. Let us create a our own custom exception
________________________________________________________
class SingletonException extends RuntimeException
{
//new exception type for singleton classes
public SingletonException()
{
super();
}
//-----------------------------------------------
public SingletonException(String s)
{
super(s);
}
}
________________________________________________________
It is better to have custom exception type so that the compiler will warn us of the type of exception we must catch when we attempt to create an instance of class PrintSpooler
Code to implement a Singleton Design pattern using above approach .
________________________________________________________
class PrintSpooler
{
//this is a prototype for a printer-spooler class
//such that only one instance can ever exist
static boolean
instance_flag=false; //true if 1 instance
public PrintSpooler() throws SingletonException
{
if (instance_flag)
throw new SingletonException("Only one spooler allowed");
else
instance_flag = true; //set flag for 1 instance
System.out.println("spooler opened");
}
//-------------------------------------------
public void finalize()
{
instance_flag = false; //clear if destroyed
}
}
public class singleSpooler
{
static public void main(String argv[])
{
PrintSpooler pr1, pr2;
//open one spooler--this should always work
System.out.println("Opening one spooler");
try{
pr1 = new PrintSpooler();
}catch (SingletonException e)
{System.out.println(e.getMessage());}
//try to open another spooler --should fail
System.out.println("Opening two spoolers");
try{
pr2 = new PrintSpooler();
}catch (SingletonException e)
{System.out.println(e.getMessage());}
}
}
Output of this program is:
Opening one spooler
printer opened
Opening two spoolers
Only one spooler allowed
________________________________________________________
§ Second approach to implement a Singleton Design Pattern is declare the class final and all methods are declared static, meaning that the class cannot be extended. There is singleton class in the standard Java class libraries i.e. Math class.
Below code demonstrates the second approach to implement the Singleton design pattern
________________________________________________________
final class PrintSpooler
{
//a static class implementation of Singleton pattern
static public void print(String s)
{
System.out.println(s);
}
}
public class staticPrint
{
public static void main(String argv[])
{
Printer.print("here it is");
}
}
__________________________________________________________
§ Another approach to implement a Singleton Design pattern is to is to create Singletons using a static method to issue and keep track of instances. To prevent object creation more than once , we make the constructor private so that instance can only be created only within the static method of the class.
Below code shows Creating Singleton Using a Static Method
______________________________________________________
class iSpooler {
//this is a prototype for a printer-spooler class
//such that only one instance can ever exist
static boolean instance_flag = false; //true if 1 instance
//the constructor is privatized-
//but need not have any content
private iSpooler() { }
//static Instance method returns one instance or null
static public iSpooler Instance(){
if (! instance_flag)
{
instance_flag = true;
return new iSpooler(); //only callable from //within
}
else
return null; //return no further instances
}
public void finalize()
{
instance_flag = false;
}
}
public class TestPooler{
public static void main(String args[]){
iSpooler pr1, pr2;
//open one spooler--this should always work
System.out.println("Opening one spooler");
pr1 = iSpooler.Instance();
if(pr1 != null)
System.out.println("got 1 spooler");
//try to open another spooler --should fail
System.out.println("Opening two spoolers");
pr2 = iSpooler.Instance();
if(pr2 == null)
System.out.println("no instance available");
//fails at compile time because constructor is privatized
iSpooler pr3 = new iSpooler();
}
}
__________________________________________________________
Main advantage of this approach is we don't have to worry about the exception handling
Other Consequences of the Singleton Pattern
1. It can be difficult to subclass a Singleton, since this can only work if the base Singleton class has not yet been instantiated.
2. You can easily change a Singleton to allow a small number of instances where this is allowable and meaningful.