Singleton Pattern is a #Design Pattern that ensure a class has only one instance and can be accessed globally. This could be done by having the class to track its sole instance and guarantee that no other instance can be created even when requested. The access should be done in class operation.
The Gang of Four advised to Singleton Pattern when:
- There must be exactly one instance of a class, and it must be accessible to clients from a well-known access point.
- The sole instance should be extensible by subclassing, and clients should be able to use the extended instance without code modification.
In Case 2, we could implement what is called as registry of singletons where clients could register the subclass (using the Singleton’s class operation) into a well-known registry (e.g., a string list) which could be lookup later. Upon the instantiation, the object should register itself to the Singleton with its constructor.
The Singleton Pattern can be implemented using static variable _instance
for tracking in #cpp:
class Singleton {
public:
static Singleton& Instance();
Singleton(const Singleton&) = delete; // no copy constructor
Singleton(Singleton&&) = delete; // no move constructor
Singleton& operator=(const Singleton&) = delete; // no copy operator
Singleton& operator=(Singleton&&) = delete; // no move operator
protected:
Singleton(); // instantiation will fail since constructor is not accessible
// to others
private:
static Singleton& _instance;
};
Singleton& Singleton::_instance = 0;
Singleton& Singleton::Instance() {
if (_instance == 0) {
_instance = new Singleton;
}
return _instance;
}
However, Singleton Pattern’s massive drawback is it hides dependencies and increase coupling# as Singleton violates the Single Responsibility Principle (SRP). This makes Unit Testing on the Singleton and the codebase overall hard as there is hardly any circumvention to prevent creating Singleton without affecting the state of the program.
Enforcing to have only one instance of object can be done by creating just one instance of the object. And if global is needed, just use a global variable.