Skip to content

Singleton Pattern

  • It comes under creational pattern as this pattern provides one of the best ways to create an object.
  • This pattern involves a single class which is responsible to create an object while making sure that only single object gets created. This class provides a way to access its only object which can be accessed directly without need to instantiate the object of the class.

Applicability:

  • Use the Singleton pattern when a class in your program should have just a single instance available to all clients; for example, a single database object shared by different parts of the program.
  • Use the Singleton pattern when you need stricter control over global variables.
  • For accessing cache-memory, database connection, drivers, logging. etc.

Pros and Cons

Pros Cons
control access to shared resources (databases; files etc) tight coupling -> complication for scaling and testing
global access point for singletoned instances static memory allocation
one time initialization hidden dependencies in the code
ensuring maximum number of instances per object violation of single responsibility principle
complications in multithreaded solutions

Class Diagram

Singleton Pattern

Issues with Singleton Testing

  • Singleton is not testable because:
    • As the singleton object acts as a global variable in the program, the change in state of the singleton object will affect the state of the whole program.
    • While two or many objects in the program tries to mutate the state of the program, it may enter the race condition.
    • The unit tests are independent of each other, but with the singleton object, the tests are not independent, because they depend on the singleton object.
  • Singleton is not thread-safe.
  • Singleton is not mockable.

Implementation

Step 1

Create a Singleton Class.
SingleObject.java

public class SingleObject {
   //create an object of SingleObject
   private static SingleObject instance = new SingleObject();

   //make the constructor private so that this class cannot be
   //instantiated
   private SingleObject(){}

   //Get the only object available
   public static SingleObject getInstance(){
      return instance;
   }

   public void showMessage(){
      System.out.println("Hello World!");
   }
}

Step 2

Get the only object from the singleton class.
SingletonPatternDemo.java

public class SingletonPatternDemo {
   public static void main(String[] args) {
      //illegal construct
      //Compile Time Error: The constructor SingleObject() is not visible
      //SingleObject object = new SingleObject();

      //Get the only object available
      SingleObject object = SingleObject.getInstance();

      //show the message
      object.showMessage();
   }
}

Output

Hello World!

Example:

Counter

Counter.java

public class Counter {
   //create an object of Counter
   private static Counter instance = new Counter();
   private static int count = 1;

   //make the constructor private so that this class cannot be
   //instantiated
   private Counter(){}

   //Get the only object available
   public static Counter getInstance(){
      return instance;
   }

   public void increment(){
      count++;
   }

   public void decrement(){
        count--;
   }

   public void showCount(){
        System.out.println("Count: " + count);
   }
}
SingleCounterDemo.java
public class SingleCounterDemo {
    public static void main(String[] args) {
        //create an object of Counter
        Counter counter_one = Counter.getInstance();
        Counter counter_two = Counter.getInstance();

        // Display both counts
        counter_one.showCount();
        counter_two.showCount();

        // Increment counter one.
        counter_one.increment();

        // Display both counts
        counter_one.showCount();
        counter_two.showCount();

        // Increment counter two.
        counter_two.increment();

        // Display both counts
        counter_one.showCount();
        counter_two.showCount();
    }
}

Output

Count: 1
Count: 1
Count: 2
Count: 2
Count: 3
Count: 3

Database Connection

JDBCSingleton.java

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DatabaseConnection {

    private static Connection con = null;

    static
    {
        String url = "jdbc:mysql:// localhost:3306/org";
        String user = "root";
        String pass = "root";
        try {
            Class.forName("com.mysql.jdbc.Driver");
            con = DriverManager.getConnection(url, user, pass);
        }
        catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
    }
    public static Connection getConnection()
    {
        return con;
    }
}