Singleton Design Pattern For Interviews

Introduction

Singleton is a popular topic that you will encounter at least once during your job search. This short tutorial describes three approaches to implement a singleton class.

Singleton Pattern

A singleton is simply a class that is instantiated exactly once. We want a single instance of a particular object in the memory. The common approaches are based on creating three main elements in the class:

  • private constructor: to guarantee exactly one instance will exist once the class is initialized
  • private static member: to make sure that the instance is only accessible only within its own class
  • public static function: to access the single instance

Approach 1: Instantiate the singleton object directly in the definition of the instance reference

We create a private static final variable in the class, usually naming it as “instance”. All calls to Workout.getInstance return the same object reference. No other Workout instance will be created.

public class Workout {

    //Create private static final variable in the class
    private static final Workout instance = new Workout();

    //Create private constructor
    private Workout() { }

    //Access the instance via static method, name it as getInstance()
    public static Workout getInstance() {
        return instance;
    }

    public static void main(String[] args) {
        Workout w1 = Workout.getInstance();
        Workout w2 = Workout.getInstance();
        System.out.println(w1.equals(w2));
    }
}

Approach 2: Static initialization block

We create a singleton using a static initialization block instead of using a private constructor. A static initialization block allows additional steps to be taken to set up the singleton after it has been created.

public class Workout {

    private static final Workout instance;

    //Create a singleton using a static initialization block
    static {
        instance = new Workout();
    }

    //Access the instance via static method
    public static Workout getInstance() {
        return instance;
    }

    public static void main(String[] args) {
        Workout w1 = Workout.getInstance();
        Workout w2 = Workout.getInstance();
        System.out.println(w1.equals(w2));
    }
}

Approach 3: Lazy Instantiation

Lazy instantiation is different from previous approaches in that we delay the creation of the singleton until it is requested by the client. In other words, we do not create the singleton object when the class is loaded.

public class Workout {

    private static Workout instance;
    private Workout(){ }

    public static Workout getInstance() {
        if (instance == null) {
            instance = new Workout();
        }
        return instance;
    }

    public static void main(String[] args) {
        Workout w1 = Workout.getInstance();
        Workout w2 = Workout.getInstance();
        System.out.println(w1.equals(w2));
    }
}

Follow-up Questions

If you answer how to implement a singleton pattern, you will probably get follow-up questions, such as:

  • How do you make a Singleton thread-safe?
  • Describe me a scenario where you need to use a Singleton pattern? (tip: Logger)
  • What is the relationship with Singleton and Spring Bean Scopes?

References

  • OCP: Oracle Certified Professional Java SE 8 Programmer II Study Guide, by Jeanne Boyarsky
  • Effective Java, Third Edition, by Joshua Bloch

Leave a Reply

Your email address will not be published.