Singleton pattern

In object-oriented programming, the singleton pattern is a software design pattern that restricts the instantiation of a class to a singular instance. It is one of the well-known "Gang of Four" design patterns, which describe how to solve recurring problems in object-oriented software.[1] The pattern is useful when exactly one object is needed to coordinate actions across a system.
More specifically, the singleton pattern allows classes to:[2]
- Ensure they only have one instance
- Provide easy access to that instance
- Control their instantiation (for example, hiding the constructors of a class)
The term comes from the mathematical concept of a singleton.
Common uses#edit
Singletons are often preferred to global variables because they do not pollute the global namespace (or their containing namespace). Additionally, they permit lazy allocation and initialization, whereas global variables in many languages will always consume resources.[1][3]
The singleton pattern can also be used as a basis for other design patterns, such as the abstract factory, factory method, builder and prototype patterns. Facade objects are also often singletons because only one facade object is required.
Logging is a common real-world use case for singletons, because all objects that wish to log messages require a uniform point of access and conceptually write to a single source.[4]
In Scala, the object keyword essentially defines a singleton object; the compiler creates exactly one instance of this structure, initializes it lazily the first time it is referenced, and makes it globally accessible. Defining a class and object of the same name creates a "companion object", which are Scala's equivalent of Java's static methods (which Scala does not have).
In a dependency injection framework, a singleton is a service lifetime policy where the container creates only one instance of the class and shares that exact instance across the entire application; dependency injection singletons therefore are regular service classes rather than classes with private constructors and a static instance method.
Implementations#edit
Implementations of the singleton pattern ensure that only one instance of the singleton class ever exists and typically provide global access to that instance.
Typically, this is accomplished by:
- Declaring all constructors of the class to be private, which prevents it from being instantiated by other objects
- Providing a static method that returns a reference to the instance
The instance is usually stored as a private static variable; the instance is created when the variable is initialized, at some point before when the static method is first called.
Singletons are typically final, to enforce that only one instance exists by blocking inheritance; however, it may be intentionally not final in cases such as the multiton pattern.
Eagerly-instantiated#edit
The traditional, eagerly-instantiated implementation, in Java, is as follows:
public final class Singleton {
private static final Singleton INSTANCE = new Singleton(); // declaration class variable
private int value;
private Singleton() {}
// defines a class operation that lets clients access its unique instance
public static Singleton instance() {
return INSTANCE;
}
public int getValue() {
return value;
}
public void setValue(int v) {
value = v;
}
}
In C++, the implementation is more intricate; the Java implementation is implicitly thread-safe, but the eager singleton in C++ requires double-checked locking with lock/mutex to guarantee thread safety. Additionally, special member functions must be made either private or deleted to ensure the invariant of only one instance existing is upheld.
import std;
using std::mutex;
using std::scoped_lock;
class Singleton final {
private:
inline static Singleton* inst = nullptr;
inline static mutex m; // Mutex for syncrhonized initialization
int value;
Singleton() = default; // no public constructor
~Singleton() = default; // no public destructor
public:
static Singleton& instance() {
// First check (for pre-initialization)
if (!inst) {
// Lock the mutex before creation
scoped_lock<mutex> lock(m);
// Second check uses a lock to prevent race conditions
if (!inst) {
inst = new Singleton();
}
}
// After initialization, checks are bypassed entirely
return *inst;
}
Singleton(const Singleton&) = delete("Copy construction disabled");
Singleton& operator=(const Singleton&) = delete("Copy assignment disabled");
// optional cleanup method; not necessary
static void reset() {
scoped_lock<mutex> lock(m);
delete inst;
inst = nullptr;
}
[[nodiscard]]
int getValue() const noexcept {
return value;
}
void setValue(int v) noexcept {
value = v;
}
};
int main() {
Singleton::instance().setValue(42);
std::println("value = {}", Singleton::instance().getValue()); // prints "value = 42"
Singleton::reset();
}
Meyers singleton#edit
This is an implementation of the Meyers singleton, so named after Scott Meyers, author of More Effective C++, due to his recommendation of this implementation.[5] This implementation is lazily instantiated, only constructing the instance the first time the execution reaches the definition line inside instance(), never allocating/constructing the object if instance() is never called. This initialization is guaranteed (since C++11) to be thread-safe without needing manual locks, through function-local static initialization.[6] The Meyers singleton does not include a reset() method (unlike the earlier traditional implementation; however, one can be implemented if the singleton is held using a unique pointer), and destruction occurs at program exit (like all static variables). The program output is the same as above.
import std;
class Singleton final {
private:
Singleton() = default;
int value;
public:
// The destructor must be private to allow the runtime to destroy it at program end
~Singleton() = default;
static Singleton& instance() {
static Singleton instance;
return instance;
}
[[nodiscard]]
int getValue() const noexcept {
return value;
}
void setValue(int v) noexcept {
value = v;
}
};
int main() {
Singleton::instance().setValue(42);
std::println("value = {}", Singleton::instance().getValue()); // prints "value = 42"
}
While the Meyers singleton is mostly unique to C++ due to C++'s function-local static variables with lazy thread-safe initialization, it can still be emulated in other languages. For example, in Java, one can use the initialization-on-demand holder idiom:
public final class Singleton {
private Singleton() {}
private static class Holder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton instance() {
return Holder.INSTANCE;
}
}
Enum singletons#edit
In Java, because enums are full classes (rather than just integral constants), an enum can be used to implement a singleton; any enum E in Java is implicitly final and inherits from java.lang.Enum<E>.
public enum Singleton {
INSTANCE;
// fields and methods can be added here
public void foo() {
System.out.println("Some singleton operation here");
}
}
Lazy initialization#edit
A singleton implementation may use lazy initialization in which the instance is created when the static method is first invoked. In multithreaded programs, this can cause race conditions that result in the creation of multiple instances. The following Java 5+ example[7] is a thread-safe implementation, using lazy initialization with double-checked locking.
public final class Singleton {
private static volatile Singleton instance = null;
private Singleton() {}
public static Singleton instance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
In a manner similar to the Meyers singleton, one can use System.Lazy<T> in C# to use lazy initialization:[8]
using System;
public sealed class Singleton
{
private static readonly Lazy<Singleton> _instance = new(() => new Singleton());
public static Singleton Instance => _instance.Value;
private Singleton() {}
}
Criticism#edit
Some consider the singleton to be an anti-pattern that introduces global state into an application, often unnecessarily. This introduces a potential dependency on the singleton by other objects, requiring analysis of implementation details to determine whether a dependency actually exists.[9] This increased coupling can introduce difficulties with unit testing.[10] In turn, this places restrictions on any abstraction that uses the singleton, such as preventing concurrent use of multiple instances.[10][11][12]
Singletons also violate the single-responsibility principle because they are responsible for enforcing their own uniqueness along with performing their normal functions.[10]
Avoidance through dependency injection#edit
Dependency injection can be used to avoid the singleton pattern. The singleton pattern enforces a structural restriction of only one instance of a class, but dependency injection focuses on how dependencies are passed around, avoiding the necessity of objects to look up their own global state.[13]
For example, in the following example, the OrderService is tightly coupled to DatabaseConnection; the database cannot be swapped and a different instance cannot be used.
// a concrete singleton class
final class DatabaseConnection {
private static DatabaseConnection instance;
private DatabaseConnection() {
// database resource initialization
}
public static synchronized DatabaseConnection instance() {
if (instance == null) {
instance = new DatabaseConnection();
}
return instance;
}
public void executeQuery(String sql) {
System.out.printf("Executing: %s%n");
}
}
// a tightly-coupled consumer class
class OrderService {
public void placeOrder(String orderId) {
// hardcoded dependency lookup makes this impossible to unit test
DatabaseConnection db = DatabaseConnection.instance();
db.executeQuery(String.format("INSERT INTO orders VALUES ('%s')"));
}
}
Dependency injection avoids asking how the database is created, or how many instances exist, and only asks for the Database interface in its constructor:
// an abstract interface
interface Database {
void executeQuery(String sql);
}
// implement the concrete class (no singleton logic)
class SqlDatabase implements Database {
@Override
public void executeQuery(String sql) {
System.out.println("Executing SQL: %s", sql);
}
}
// the consumer class accepts dependency via constructor injection
class OrderService {
private final Database db;
// The dependency is injected from the outside
public OrderService(Database db) {
this.db = db;
}
public void placeOrder(String orderId) {
db.executeQuery(String.format("INSERT INTO orders VALUES ('%s')", orderId));
}
}
See also#edit
References#edit
- ^ a b Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley. pp. 127ff. ISBN 0-201-63361-2.
- ^ "The Singleton design pattern - Problem, Solution, and Applicability". w3sDesign.com. Retrieved 2017-08-16.
- ^ Soni, Devin (31 July 2019). "What Is a Singleton?". BetterProgramming. Retrieved 28 August 2021.
- ^ Rainsberger, J.B. (1 July 2001). "Use your singletons wisely". IBM. Archived from the original on 24 February 2021. Retrieved 28 August 2021.
- ^ Scott Meyers (1997). More Effective C++. Addison Wesley. pp. 146 ff. ISBN 0-201-63371-X.
- ^ Microsoft Learn (15 February 2022). "Storage classes". learn.microsoft.com. Microsoft Learn.
- ^ Eric Freeman, Elisabeth Freeman, Kathy Sierra, and Bert Bates (October 2004). "5: One of a Kind Objects: The Singleton Pattern". Head First Design Patterns (First ed.). O'Reilly Media, Inc. p. 182. ISBN 978-0-596-00712-6.
- ^ Microsoft Learn. "Lazy<T> Class". learn.microsoft.com. Microsoft Learn. Retrieved 6 July 2026.
- ^ "Why Singletons Are Controversial". Google Code Archive. Archived from the original on 6 May 2021. Retrieved 28 August 2021.
- ^ a b c Button, Brian (25 May 2004). "Why Singletons are Evil". Being Scott Densmore. Microsoft. Archived from the original on 15 July 2021. Retrieved 28 August 2021.
- ^ Steve Yegge. Singletons considered stupid, September 2004
- ^ Hevery, Miško, "Global State and Singletons", Clean Code Talks, 21 November 2008.
- ^ Microsoft Learn (11 March 2026). "Dependency injection guidelines". learn.microsoft.com. Microsoft Learn.
External links#edit
- Complete article "Java Singleton Pattern Explained"
- Four different ways to implement singleton in Java "Ways to implement singleton in Java"
This article is mirrored from “Singleton pattern” on English Wikipedia, revision 1380777641, written by Wikipedia's contributors and licensed CC BY-SA 4.0. Editing it here creates a Quire copy with its own history.
Synced with Wikipedia revision 1380777641 · just now