Work when you want, how you want, wherever you want in the world.

Singleton Design Pattern

Oct 25, 2023

Lone person standing in the middle of a road.

The Singleton Design Pattern is one of the most commonly used design patterns in software engineering. It falls under the category of creational design patterns, and its primary goal is to ensure that a class has only one instance during the lifetime of an application while providing a global point of access to that instance. In other words, it ensures that there is a single point of control for that class. This can be particularly useful when you want to maintain a global state or control access to resources such as a database connection, a configuration manager, or a thread pool.

Structure

The Singleton pattern typically consists of a Singleton Class and a client. A Singleton class should have a private constructor to prevent direct instantiation, a private static instance variable to store the single instance, and a public static method to access the instance. The client is any code or class that wants to use the Singleton. It accesses the Singleton instance through the static method provided by the Singleton class.

Implementation

Here's a common implementation of the Singleton Design Pattern in Java:

public class Singleton {
    private static Singleton instance;
    
    // Private constructor to prevent direct instantiation
    private Singleton() {
        // Initialization code if needed
    }
    
    // Static method to provide access to the Singleton instance
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
    
    // Other methods and attributes of the Singleton class
}

Implementing a Singleton in C# is nearly identical to the Java implementation.

Usage

You can use the Singleton pattern as follows:


Singleton singletonInstance1 = Singleton.getInstance();
Singleton singletonInstance2 = Singleton.getInstance();

// Both singletonInstance1 and singletonInstance2 refer to the same Singleton instance

Advantages

The Singleton pattern ensures that there is only one instance of the class, which can be important for managing shared resources or maintaining a global state. The instance is created only when it's first needed, which can save resources and improve performance. The Singleton pattern provides a global point of access to the Singleton instance, making it easy for clients to use the instance.

Disadvantages

The Singleton pattern is not Suitable for multithreading. The basic Singleton implementation is not thread-safe. If multiple threads attempt to access the Singleton instance simultaneously, it can lead to the creation of multiple instances. You can address this issue using techniques like double-check locking or synchronization. To make the Singleton thread-safe, you can use a lock or the Lazy<T> class in C#. Here's an example using the Lazy<T> class:


public class Singleton
{
    private static readonly Lazy lazyInstance = new Lazy(() => new Singleton());
    
    // Private constructor to prevent direct instantiation
    private Singleton()
    {
        // Initialization code if needed
    }
    
    public static Singleton Instance
    {
        get
        {
            return lazyInstance.Value;
        }
    }
    
    // Other methods and attributes of the Singleton class
}

By using Lazy<Singleton>, the Singleton instance is initialized only once and in a thread-safe manner when it's first accessed. This Lazy<T> approach is preferred for creating thread-safe singletons in C#. It ensures that the instance is created only when it's actually needed.

You can implement a lazy object approach in Java similar to C# by using the java.util.concurrent package's java.util.concurrent.atomic.AtomicReference class along with the java.util.concurrent.locks.ReentrantLock. This approach allows you to create a lazy Singleton with thread safety, ensuring that the instance is initialized only when it's first accessed. Here's an example:

import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantLock;

public class LazySingleton {
    private static final AtomicReference instance = new AtomicReference<>();
    private static final ReentrantLock lock = new ReentrantLock();

    private LazySingleton() {
        // Initialization code if needed
    }

    public static LazySingleton getInstance() {
        if (instance.get() == null) {
            lock.lock(); // Acquire a lock to ensure thread safety
            try {
                if (instance.get() == null) {
                    instance.set(new LazySingleton());
                }
            } finally {
                lock.unlock(); // Release the lock
            }
        }
        return instance.get();
    }

    // Other methods and attributes of the Singleton class
}

In this Java example:

Other Considerations

While it can be useful for managing shared resources, a Singleton that is widely accessed and modified can lead to tightly coupled code and issues related to maintaining global state. Testing singletons can be difficult because they introduce a global state. You may need to use mock objects or other techniques to isolate the Singleton during testing. Depending on how it's used, a Singleton may take on multiple responsibilities, which can violate the Single Responsibility Principle. Careful design is needed to avoid this problem.

In summary, the Singleton Design Pattern is a valuable tool for ensuring that there's only one instance of a class, and it provides a global point of access to that instance. However, it should be used judiciously and with consideration of potential thread safety and maintenance issues.

Latest Articles

Single Responsibility Principle

The Single Responsibility Principle (SRP) is one of the five SOLID principles of object-oriented programming and design, introduced by Robert C...

Read More

Singleton Design Pattern

The Singleton Design Pattern is one of the most commonly used design patterns in software engineering...

Read More

MVC: Model-View-Controller Design Pattern

Model-View-Controller (MVC) is a software architectural pattern used in the design and development of applications, particularly in the context of user interfaces...

Read More

The MEAN Stack

The MEAN stack is a popular technology stack used for building web applications...

Read More

The Internet of Things

The Internet of Things (IoT) refers to the interconnection of everyday objects and devices to the internet, allowing them to collect and exchange data with each other and with centralized systems or applications...

Read More

The Cloud

Cloud computing is a technology that enables users to access and use computing resources (such as servers, storage, databases, networking, software, and more) over the internet and on-demand...

Read More