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]
The term comes from the mathematical concept of a singleton.
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]
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:
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 C++23 implementation is based on the pre-C++98 implementation in the book [ citation needed ].
importstd;classSingleton{public:// defines an class operation that lets clients access its unique instance.staticSingleton&get(){// may be responsible for creating its own unique instance.if(nullptr==instance)instance=newSingleton;return*instance;}Singleton(constSingleton&)=delete;// rule of threeSingleton&operator=(constSingleton&)=delete;staticvoiddestruct(){deleteinstance;instance=nullptr;}// existing interface goes hereintgetValue(){returnvalue;}voidsetValue(intvalue_){value=value_;}private:Singleton()=default;// no public constructor~Singleton()=default;// no public destructorstaticSingleton*instance;// declaration class variableintvalue;};Singleton*Singleton::instance=nullptr;// definition class variableintmain(){Singleton::get().setValue(42);std::println("value={}",Singleton::get().getValue());Singleton::destruct();}
The program output is
value=42
This is an implementation of the Meyers singleton [5] in C++11. The Meyers singleton has no destruct method. The program output is the same as above.
importstd;classSingleton{public:staticSingleton&get(){staticSingletoninstance;returninstance;}intgetValue(){returnvalue;}voidsetValue(intvalue_){value=value_;}private:Singleton()=default;~Singleton()=default;intvalue;};intmain(){Singleton::get().setValue(42);std::println("value={}",Singleton::get().getValue());}
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 [6] is a thread-safe implementation, using lazy initialization with double-checked locking.
publicclassSingleton{privatestaticvolatileSingletoninstance=null;privateSingleton(){}publicstaticSingletongetInstance(){if(instance==null){synchronized(Singleton.class){if(instance==null){instance=newSingleton();}}}returninstance;}}
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. [7] This increased coupling can introduce difficulties with unit testing. [8] In turn, this places restrictions on any abstraction that uses the singleton, such as preventing concurrent use of multiple instances. [8] [9] [10]
Singletons also violate the single-responsibility principle because they are responsible for enforcing their own uniqueness along with performing their normal functions. [8]
In programming language theory, lazy evaluation, or call-by-need, is an evaluation strategy which delays the evaluation of an expression until its value is needed and which also avoids repeated evaluations.
The abstract factory pattern in software engineering is a design pattern that provides a way to create families of related objects without imposing their concrete classes, by encapsulating a group of individual factories that have a common theme without specifying their concrete classes. According to this pattern, a client software component creates a concrete implementation of the abstract factory and then uses the generic interface of the factory to create the concrete objects that are part of the family. The client does not know which concrete objects it receives from each of these internal factories, as it uses only the generic interfaces of their products. This pattern separates the details of implementation of a set of objects from their general usage and relies on object composition, as object creation is implemented in methods exposed in the factory interface.
In computer programming, lazy initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed. It is a kind of lazy evaluation that refers specifically to the instantiation of objects or other resources.
In object-oriented programming, the factory method pattern is a design pattern that uses factory methods to deal with the problem of creating objects without having to specify their exact classes. Rather than by calling a constructor, this is accomplished by invoking a factory method to create an object. Factory methods can be specified in an interface and implemented by subclasses or implemented in a base class and optionally overridden by subclasses. It is one of the 23 classic design patterns described in the book Design Patterns and is subcategorized as a creational pattern.
The prototype pattern is a creational design pattern in software development. It is used when the types of objects to create is determined by a prototypical instance, which is cloned to produce new objects. This pattern is used to avoid subclasses of an object creator in the client application, like the factory method pattern does, and to avoid the inherent cost of creating a new object in the standard way when it is prohibitively expensive for a given application.
In software design and engineering, the observer pattern is a software design pattern in which an object, named the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.
In software engineering, double-checked locking is a software design pattern used to reduce the overhead of acquiring a lock by testing the locking criterion before acquiring the lock. Locking occurs only if the locking criterion check indicates that locking is required.
A method in object-oriented programming (OOP) is a procedure associated with an object, and generally also a message. An object consists of state data and behavior; these compose an interface, which specifies how the object may be used. A method is a behavior of an object parametrized by a user.
In object-oriented programming such as is often used in C++ and Object Pascal, a virtual function or virtual method is an inheritable and overridable function or method that is dispatched dynamically. Virtual functions are an important part of (runtime) polymorphism in object-oriented programming (OOP). They allow for the execution of target functions that were not precisely identified at compile time.
This article compares two programming languages: C# with Java. While the focus of this article is mainly the languages and their features, such a comparison will necessarily also consider some features of platforms and libraries.
In class-based, object-oriented programming, a constructor is a special type of function called to create an object. It prepares the new object for use, often accepting arguments that the constructor uses to set required member variables.
The syntax of Java is the set of rules defining how a Java program is written and interpreted.
In computer programming, thread-local storage (TLS) is a memory management method that uses static or global memory local to a thread. The concept allows storage of data that appears to be global in a system with separate threads.
In the C++ programming language, new and delete are a pair of language constructs that perform dynamic memory allocation, object construction and object destruction.
C++11 is a version of a joint technical standard, ISO/IEC 14882, by the International Organization for Standardization (ISO) and International Electrotechnical Commission (IEC), for the C++ programming language. C++11 replaced the prior version of the C++ standard, named C++03, and was later replaced by C++14. The name follows the tradition of naming language versions by the publication year of the specification, though it was formerly named C++0x because it was expected to be published before 2010.
In software engineering, the initialization-on-demand holder idiom is a lazy-loaded singleton. In all versions of Java, the idiom enables a safe, highly concurrent lazy initialization of static fields with good performance.
Generics are a facility of generic programming that were added to the Java programming language in 2004 within version J2SE 5.0. They were designed to extend Java's type system to allow "a type or method to operate on objects of various types while providing compile-time type safety". The aspect compile-time type safety required that parametrically polymorphic functions are not implemented in the Java virtual machine, since type safety is impossible in this case.
In object-oriented computer programming, a null object is an object with no referenced value or with defined neutral (null) behavior. The null object design pattern, which describes the uses of such objects and their behavior, was first published as "Void Value" and later in the Pattern Languages of Program Design book series as "Null Object".
This article describes the syntax of the C# programming language. The features described are compatible with .NET Framework and Mono.
In software engineering, the module pattern is a design pattern used to implement the concept of software modules, defined by modular programming, in a programming language with incomplete direct support for the concept.
{{cite book}}
: CS1 maint: multiple names: authors list (link){{cite book}}
: CS1 maint: multiple names: authors list (link)This article's use of external links may not follow Wikipedia's policies or guidelines.(November 2016) |