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. The pattern is useful when exactly one object is needed to coordinate actions across a system. More specifically, the singleton pattern allows classes to:
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 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. 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.
Implementations 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.
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. The Meyers singleton has no destructor method. The program output is the same as above.
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:
Lazy initialization 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 is a thread-safe implementation, using lazy initialization with double-checked locking.
In a manner similar to the Meyers singleton, one can use System.Lazy<T> in C# to use lazy initialization:
Criticism 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. This increased coupling can introduce difficulties with unit testing. In turn, this places restrictions on any abstraction that uses the singleton, such as preventing concurrent use of multiple instances. Singletons also violate the single-responsibility principle because they are responsible for enforcing their own uniqueness along with performing their normal functions.
Avoidance through dependency injection 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. 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.
Dependency injection avoids asking how the database is created, or how many instances exist, and only asks for the Database interface in its constructor:
See also Initialization-on-demand holder idiom Multiton pattern Dependency injection Software design pattern
References
External links
Complete article "Java Singleton Pattern Explained" Four different ways to implement singleton in Java "Ways to implement singleton in Java"
