1. Definition

The Singleton Design Pattern ensures that a class has only one instance and provides a global point of access to that instance. It ensures that the single instance can be accessed globally without creating a new one every time it’s needed.

2. Problem Statement

How can an application ensure that a particular class has only one instance, and how can it easily provide access to that single instance from any point in the app?

3. Solution

Make the class itself responsible for keeping track of its sole instance by ensuring that no other instance can be created and providing a mechanism to access the single instance.

4. Real-World Use Cases

1. Database Connection Pools where we need a single set of pooled connections.

2. Logger Classes, where logs come from various parts of an application.

3. Configuration Management, where you want to ensure that configurations are not overridden.

4. Caching, where we avoid redundant data or computations.

5. Implementation Steps

1. Declare a private static instance of the class.

2. Make the constructor private to prevent instantiation from outside.

3. Provide a public static method to get the instance of the class.

6. Implementation

// Singleton Class
class Singleton {
    // Step 1: Declare a private static instance
    private static Singleton uniqueInstance;

    // Step 2: Make the constructor private
    private Singleton() {}

    // Step 3: Provide a public static method to get the instance
    public static Singleton getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }
}

// Test Singleton
public class SingletonDemo {
    public static void main(String[] args) {
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();

        System.out.println("Instance 1 hash:" + instance1.hashCode());
        System.out.println("Instance 2 hash:" + instance2.hashCode());
    }
}

Output:

Instance 1 hash: [hashcode]
Instance 2 hash: [hashcode]
(Note: [hashcode] will be a specific number and should be the same for both instances)

Explanation:

The Singleton pattern ensures that there's only one instance of the Singleton class in the JVM and provides a global point of access to it. In the provided Java example, the two instances instance1 and instance2 obtained from Singleton.getInstance() method are, in fact, the same object, which is proven by their identical hash codes.

7. When to use?

The Singleton pattern is applicable when:

1. You want to ensure a class has only one instance.

2. The single instance should be extendable by subclassing.

3. The instance should be accessible from any point in the application.