Design Patterns: Singleton

Introduction

The Singleton pattern is a design pattern that restricts the instantiation of a class to a single object. This ensures that there is one and only one instance of the class throughout the application, providing a global point of access to that instance. It is commonly used when exactly one object is needed to coordinate actions across the system.

Purpose

Ensures that a class has only one instance and provides a global point of access to it.

Use cases

  • Database connections
  • Logging
  • Cache management
  • Global state & more
1class Singleton:
2 _instance = None
3
4 def __new__(cls, *args, **kwargs):
5 if not cls._instance:
6 cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
7 return cls._instance
8
9# Usage
10obj1 = Singleton()
11obj2 = Singleton()
12print(obj1 is obj2) # True
1class Singleton {
2 constructor() {
3 if (Singleton.instance) {
4 return Singleton.instance
5 }
6 Singleton.instance = this
7 }
8}
9
10const obj1 = new Singleton()
11const obj2 = new Singleton()
12console.log(obj1 === obj2)
1class Singleton {
2 static final Singleton _instance = Singleton._internal();
3
4 Singleton._internal();
5
6 factory Singleton() {
7 return _instance;
8 }
9}
10
11// Usage
12void main() {
13 var obj1 = Singleton();
14 var obj2 = Singleton();
15 print(obj1 == obj2); // true
16}
1class Logger
2 @instance = new
3
4 private_class_method :new
5
6 def self.instance
7 @instance
8 end
9end
10
11log1 = Logger.instance
12log2 = Logger.instance
13puts log1 == log2 # true

Conclusion

The Singleton pattern provides a controlled way to ensure a single instance of a class exists and is accessible globally. It is especially useful for managing shared resources like database connections, configuration settings, logging, or caching, while keeping the design clean and preventing multiple conflicting instances.