Singleton Design Pattern (Creational)
Singleton is a creational design pattern that lets you ensure that a class has only one instance, while providing a global access point to this instance.
Problem
Section titled βProblemβThe Singleton pattern solves two problems at the same time, violating the Single Responsibility Principle:
- Ensure that a class has just a single instance. Why would anyone want to control how many instances a class has? The most common reason for this is to control access to some shared resourceβfor example, a database or a file.
- Provide a global access point to that instance. Remember those global variables that you used to store some essential objects? While theyβre very handy, theyβre also very unsafe since any code can potentially overwrite the contents of those variables and crash the app.
Solution
Section titled βSolutionβAll implementations of the Singleton have these two steps in common:
- Make the default constructor private, to prevent other objects from using the
newoperator with the Singleton class. - Create a static creation method that acts as a constructor. Under the hood, this method calls the private constructor to create an object and saves it in a static field. All following calls to this method return the cached object.
If your code has access to the Singleton class, then itβs able to call the Singletonβs static method. So whenever that method is called, the same object is always returned.
Real-World Analogy
Section titled βReal-World AnalogyβThe Government is an excellent example of the Singleton pattern. A country can have only one official government. Regardless of the personal identities of the individuals who form a government, the title, βThe Government of X,β is a global point of access that identifies the group of people in charge.
Structure (Class Diagram)
Section titled βStructure (Class Diagram)βclassDiagram
class Singleton {
- instance: Singleton
- Singleton()
+ getInstance() Singleton
}
Pseudocode
Section titled βPseudocodeβclass Database: # The field for storing the singleton instance should be # declared static. private static field instance: Database
# The singleton's constructor should always be private to # prevent direct construction calls with the `new` operator. private constructor Database(): # Some initialization code, such as the actual # connection to a database server. # ...
# The static method that controls access to the singleton # instance. public static method getInstance(): if (Database.instance == null): acquireThreadLock(): # Ensure that the instance hasn't been created yet by another thread. if (Database.instance == null): Database.instance = new Database() return Database.instance
# Finally, any singleton should define some business logic # which can be executed on its instance. public method query(sql): # For instance, all queries of an app go through this # connection. # ...Applicability
Section titled βApplicabilityβ- Use the Singleton pattern when a class in your program should have just a single instance available to all clients; for example, a single database object shared by different parts of the program.
- Use the Singleton pattern when you need stricter control over global variables.
How to Implement
Section titled βHow to Implementβ- Add a private static field to the class for storing the singleton instance.
- Declare a public static creation method for getting the singleton instance.
- Implement βlazy initializationβ inside the static method. It should create a new object on its first call and put it into the static field. The method should always return that instance on all subsequent calls.
- Make the constructor of the class private. The static method of the class will still be able to call the constructor, but not the other objects.
- Go over the client code and replace direct calls to the singletonβs constructor with calls to its static creation method.
Pros and Cons
Section titled βPros and ConsβPros:
- You can be sure that a class has only a single instance.
- You gain a global access point to that instance.
- The singleton object is initialized only when itβs requested for the first time.
Cons:
- Violates the Single Responsibility Principle. The pattern solves two problems at the time.
- The Singleton pattern can mask bad design, for instance, when the components of the program know too much about each other.
- The pattern requires special treatment in a multithreaded environment so that multiple threads wonβt create a singleton object several times.
Relations with other Design Patterns
Section titled βRelations with other Design Patternsβ- A Facade class can often be transformed into a Singleton since a single facade object is sufficient in most cases.
- Abstract Factory, Builder, and Prototype can all be implemented as Singletons.
Code Examples
Section titled βCode ExamplesβCode Examples (C#)
Section titled βCode Examples (C#)βpublic sealed class Singleton{ private static readonly Singleton _instance = new Singleton();
public static Singleton Instance => _instance;
private Singleton() { // Private construtor }
public void DoSomething() { Console.WriteLine("Doing something..."); }}
// Usageclass Program{ static void Main() { var s1 = Singleton.Instance; var s2 = Singleton.Instance;
Console.WriteLine(s1 == s2); // True }}Code Examples (Python)
Section titled βCode Examples (Python)βclass SingletonMeta(type): """ The Singleton class can be implemented in different ways in Python. Some possible methods include: base class, decorator, metaclass. We will use a metaclass because it is best suited for this task. """
_instances = {}
def __call__(cls, *args, **kwargs): """ Possible changes to the value of the `__init__` argument do not affect the returned instance. """ if cls not in cls._instances: instance = super().__call__(*args, **kwargs) cls._instances[cls] = instance return cls._instances[cls]
class Singleton(metaclass=SingletonMeta): def some_business_logic(self): """ Finally, any singleton should define some business logic, which can be executed on its instance. """ # ...
if __name__ == "__main__": # The client code.
s1 = Singleton() s2 = Singleton()
if id(s1) == id(s2): print("Singleton works, both variables contain the same instance.") else: print("Singleton failed, variables contain different instances.")Code Examples (C++)
Section titled βCode Examples (C++)β#include <iostream>
class Singleton {private: // Eagerly created static instance static Singleton instance;
// Private constructor Singleton() { // ... }
public: // Public accessor static Singleton& Instance() { return instance; }
void DoSomething() { std::cout << "Doing something..." << std::endl; }};
// Definition of the static instanceSingleton Singleton::instance;
// Usageint main() { Singleton& s1 = Singleton::Instance(); Singleton& s2 = Singleton::Instance();
std::cout << std::boolalpha << (&s1 == &s2) << std::endl; // true
return 0;}Code Examples (Java)
Section titled βCode Examples (Java)βpublic final class Singleton {
// Eagerly created static instance private static final Singleton INSTANCE = new Singleton();
// Private constructor private Singleton() { // ... }
// Public accessor public static Singleton getInstance() { return INSTANCE; }
public void doSomething() { System.out.println("Doing something..."); }}
// Usagepublic class Program { public static void main(String[] args) { Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance();
System.out.println(s1 == s2); // true }}Code Examples (JavaScript)
Section titled βCode Examples (JavaScript)βclass Singleton { // Eagerly created static instance static #instance = new Singleton(true);
constructor(internalFlag) { if (!internalFlag) { throw new Error("Use Singleton.getInstance()"); } }
static getInstance() { return Singleton.#instance; }
doSomething() { console.log("Doing something..."); }}
// Usageconst s1 = Singleton.getInstance();const s2 = Singleton.getInstance();
console.log(s1 === s2); // trueCode Examples (Visual Basic)
Section titled βCode Examples (Visual Basic)βPublic NotInheritable Class Singleton
Private Shared ReadOnly _instance As New Singleton()
Public Shared ReadOnly Property Instance As Singleton Get Return _instance End Get End Property
Private Sub New() ' Private constructor End Sub
Public Sub DoSomething() Console.WriteLine("Doing something...") End Sub
End Class
Module Program Sub Main() Dim s1 = Singleton.Instance Dim s2 = Singleton.Instance
Console.WriteLine(s1 Is s2) ' True End SubEnd ModuleCode Examples (Rust)
Section titled βCode Examples (Rust)βuse std::sync::OnceLock;
struct Singleton;
impl Singleton { fn do_something(&self) { println!("Doing something..."); }}
// Global, single instancestatic INSTANCE: OnceLock<Singleton> = OnceLock::new();
fn instance() -> &'static Singleton { INSTANCE.get_or_init(|| Singleton)}
fn main() { let s1 = instance(); let s2 = instance();
println!("{}", std::ptr::eq(s1, s2)); // true s1.do_something();}Code Examples (PHP)
Section titled βCode Examples (PHP)β<?php
final class Singleton{ private static $instance;
private function __construct() { // Private constructor }
public static function getInstance(): Singleton { if (self::$instance === null) { self::$instance = new Singleton(); }
return self::$instance; }
public function doSomething(): void { echo "Doing something...\n"; }}
// Usage$s1 = Singleton::getInstance();$s2 = Singleton::getInstance();
echo ($s1 === $s2 ? "True" : "False"); // TrueCode Examples (Go)
Section titled βCode Examples (Go)βpackage singleton
import ( "fmt" "sync")
type singleton struct{}
var ( instance *singleton once sync.Once)
// Instance returns the single global instance.func Instance() *singleton { once.Do(func() { instance = &singleton{} }) return instance}
func (s *singleton) DoSomething() { fmt.Println("Doing something...")}
// Usagepackage main
import ( "fmt" "singleton")
func main() { s1 := singleton.Instance() s2 := singleton.Instance()
fmt.Println(s1 == s2) // true s1.DoSomething()}Code Examples (Ruby)
Section titled βCode Examples (Ruby)βclass Singleton@instance = new
private_class_method :new
def self.instance @instanceend
def do_something puts "Doing something..."endend
# Usages1 = Singleton.instances2 = Singleton.instance
puts s1.equal?(s2) # trueCode Examples (Perl)
Section titled βCode Examples (Perl)βpackage Singleton;
use strict;use warnings;
# Lexical instance (private to this file)my $instance;
# Private constructorsub new { my ($class) = @_; return bless {}, $class;}
# Public accessorsub instance { return $instance ||= Singleton->new();}
sub do_something { print "Doing something...\n";}
1; # Package must return true
# Usageuse strict;use warnings;use Singleton;
my $s1 = Singleton->instance();my $s2 = Singleton->instance();
print ($s1 == $s2 ? "True\n" : "False\n"); # True$s1->do_something();Code Examples (TypeScript)
Section titled βCode Examples (TypeScript)βclass Singleton { private static instance: Singleton = new Singleton();
private constructor() { // Private constructor }
public static get Instance(): Singleton { return Singleton.instance; }
public doSomething(): void { console.log("Doing something..."); }}
// Usageconst s1 = Singleton.Instance;const s2 = Singleton.Instance;
console.log(s1 === s2); // true