Design Patterns - SPLessons

Singleton Pattern

Chapter 3

SPLessons 5 Steps, 3 Clicks
5 Steps - 3 Clicks

Singleton Pattern

Singleton Pattern

shape Introduction

A class for which only one instance can be created is known as Singleton class. The Singleton pattern uses singleton classes because it provides global access. There are two different types of Singleton Pattern, they are:

  1. The process of creating an instance when required is known as Lazy Instantiation.
  2. The process of creating an instance at load time is known as Early Instantiation.

shape Description

One can easily pass an object resource using the Singleton Pattern. For implementing Singleton Patterns, one needs to follow different approaches, such as:

  • Using private constructor because it prevents instantiation of the class.
  • Using private static variable of the class. This is mostly used in multi-threading and database applications.

shape Advantages

Resources can be accessed in shared mode. Singleton Pattern can be implemented and designed in many ways. Some of them include:

  • Static block Initialization.
  • Enum singleton.
  • Lazy Initialization.
  • Eager Initialization.
  • Thread safe Singleton.
  • Using reflection to destroy the Singleton pattern.

shape Conceptual
figure

Establish the class of the single instance object to be in charge of creation, “initialization on first use”, and access. The single occurrence is a private static characteristic and the accessor capacity is an open static technique.

shape Examples

1.Lazy Initialization
An instance created for a class when it is required, is called as Lazy Initialization.

public class LazyInitializedSingleton 
{
private static LazyInitializedSingleton instance;
private LazyInitializedSingleton()
{
}
public static LazyInitializedSingleton getInstance()
{
if(instance == null)//instance is checked
{
instance = new LazyInitializedSingleton();
}
return instance;
}
}

2.Eager Initialization

An instance created for a class at load time, is called as Early Initialization.

public class EagerInitializedSingleton
 {
private static final EagerInitializedSingleton instance = new EagerInitializedSingleton();
private EagerInitializedSingleton()
{
}
public static EagerInitializedSingleton getInstance()//returns the instance
{
return instance;
}
}

3. Static block Initialization

The “static member function accessor” approach will not support the subclass feature of the Singleton class.

public class StaticBlockSingleton
 {
private static StaticBlockSingleton instance;
private StaticBlockSingleton(){}
static
{
try//exception may occur
{
instance = new StaticBlockSingleton();
}catch(Exception e)//exception is caught
{
throw new RuntimeException("Exception occured in creating singleton instance");
}
}
public static StaticBlockSingleton getInstance()
{
return instance;
}
}

4. Enum singleton

Enum value can be instantiated only once in a Java program. Since Java Enum values are globally accessible, it is easy for singleton. The drawback is that the enum type is inflexible. For example, it does not support lazy initialization.

public enum EnumSingleton//enum is a user defined data type
 {
INSTANCE;
public static void doSomething()
{
}
}

5. Thread safe Singleton

Thread-safety interferes with the performance due to the cost associated with the synchronized method. Although, it is required only for the first few threads, separate instances might be created. To avoid this overhead every time, double checked locking principle can be used. In this approach, the synchronized block is used inside the if condition block with an additional check to ensure that only one instance of the singleton class is created.

public class ThreadSafeSingleton 
{
private static ThreadSafeSingleton instance;
private ThreadSafeSingleton()
{
}
public static synchronized ThreadSafeSingleton getInstance()
{
if(instance == null)//instance is checked
{
instance = new ThreadSafeSingleton();
}
return instance;
}
}

6. Using reflection to destroy singleton pattern

Reflections are used for destroying the singleton pattern.

public class ReflectionSingletonTest 
{
public static void main(String[] args)//is a main method 
{
EagerSingleton instanceOne =EagerSingleton.getInstance();
EagerSingleton instanceTwo = null;
try {
Constructor c[] = EagerSingleton.class.getDeclaredConstructors();
for (Constructor constructor : c)
 {
constructor.setAccessible(true);
instanceTwo = (EagerSingleton) c.newInstance();
break;
}
} catch (Exception e)
 {
e.printStackTrace();
}
System.out.println(instanceOne.hashCode());
System.out.println(instanceTwo.hashCode());
}
}

Summary

shape Key Points

  • Singleton pattern is a simple design pattern and can be used for serialization.
  • Singleton pattern is easy to implement and has a single class which creates an object and ensures that single object is created.
  • Singleton pattern has the following principles: Single instance of a class, global access and “initialization on first use”.