DEV Community

Vivek Alhat
Vivek Alhat

Posted on

The Singleton Design Pattern

Design patterns are essential for writing clean, scalable, and maintainable code. One of the most commonly used design patterns is the Singleton Pattern. In this article, we’ll explore what the Singleton pattern is, why it’s useful, and how to implement it with an example.

What is the Singleton Design Pattern?

The Singleton pattern is a creational design pattern that ensures a class has only one instance and provides a global point of access to that instance. This pattern is useful when you need to control access to shared resources, such as logging mechanisms, configuration settings, or database connections.

Characteristics of the Singleton Pattern

  • Single Instance: Ensures that only one instance of the class exists.
  • Global Access Point: Provides a way to access the single instance.
  • Lazy Initialization: The instance is created only when it is first needed.
  • Thread Safety (Optional): In multi-threaded environments, precautions should be taken to avoid multiple instances.

How to Implement the Singleton Pattern

Let's implement a Logger class using the Singleton pattern in TypeScript:

class Logger {
  // private static instance variable
  private static instance: Logger;

  // private constructor to prevent external initialization
  private constructor() {}

  // static method to get the instance
  public static getInstance(): Logger {
    if (!Logger.instance) {
      console.log("Creating new instance");
      Logger.instance = new Logger();
    }
    return Logger.instance;
  }
}

// Usage
const logger1 = Logger.getInstance();
const logger2 = Logger.getInstance();

if (logger1 === logger2) {
  console.log("Both are the same loggers");
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  1. Private Constructor: Prevents external instantiation.
  2. Static Instance Variable: Stores the single instance.
  3. Static Method (getInstance): Ensures only one instance is created and provides global access.
  4. Lazy Initialization: The instance is created only when first accessed.
  5. Ensuring Uniqueness: Checking if logger1 === logger2 confirms that both variables reference the same instance.

Use Cases of Singleton Pattern

The Singleton pattern is useful in scenarios where multiple instances could lead to inconsistencies or unnecessary resource usage. Some common use cases include:

  1. Logging: A single instance ensures consistent logging throughout the application.
  2. Configuration Management: Prevents multiple conflicting configuration objects.
  3. Database Connection Pooling: Avoids multiple redundant connections to the database.

Pros and Cons of Singleton Pattern

Pros:

✔ It ensures a single point of access to a resource.
✔ It saves memory by preventing multiple unnecessary instances.
✔ It is useful for managing shared states like caching and logging.

Cons:

✖ It can introduce global state hence making debugging harder.
✖ It is not inherently thread-safe hence needs additional handling in multi-threaded environments.

Conclusion

The Singleton pattern is a powerful and commonly used design pattern that ensures only one instance of a class exists.

I am implementing design patterns in Go, Python, and TypeScript. You can find the repository here.

Happy coding! 🚀

Top comments (0)