What is the singleton design pattern and how does it work?
The Singleton Design Pattern is described in the legendary book “Design Patterns” by the Gang of Four.
A Singleton takes itself care of t’s instantiation and life cycle. Because the constructor is not public, it is not possible to create an object outside of the class.
Therefore it has a static method (i.e. getInstance) as global access point. It has also a private static attribute of itself, that is only instantiated one time. This way the instance method returns always the same instance.
When or why could you apply this Design Patterns?
A Singleton is used, when you want to make sure, that there’s only one Instance of a class.
For example you have a class that communicates with a serial port (COM). A serial port can only be opened once a a time. That means you can only have on Instance of the class that’s controlling the port.
It’s also used for database or API-access classes to prevent multiple connections or instantiations of the external libraries. Logging, caching or configuration are also possible candidates.
That sounds fine, but what’s the catch?
First of all: It uses a global variable. And as we all learned the hard way, global variables can make the behavior of your code unpredictable. Global state can lead to complex problems, as it can be modified anywhere in your code.
Also this violates the Single Responsibility Principle: “There should never be more than one reason for a class to change.” – Robert C. Martin
Instantiation is in my opinion a responsibility, and in medium or large scale code bases a critical.
Another drawback is tight coupling. Calling the singleton::getInstance() anywhere in your code couples it directly the singleton class.
Loose coupling is a good practice to develop maintainable and testable code.
Loose coupling and clear dependencies passed to new instances, for example by using constructor injection, allow the composition of reuse able modules at run time.
A class using the singleton is hard to test in isolation. And testing in general and also testing a module in isolation is essential for maintainable code.
To test a class which access the singleton in a method, you must find a way to replace the normally hidden instance with a stub, mock, etc.
To do this, the singleton class may have a public setInstanceForTesting method, which may not be a good idea.
Another possibility is creating a subclass with a static set method, that overrides the static instance variable (if it is protected).
The global state can also become a nightmare when testing your code. Tests fail and you have no idea why, or tests pass that should fail because the implementation is not complete yet.
You have to be careful when you test code using singletons, that the state of the previous test is removed.
If you don’t replace the singleton instance by dependency injection at least clear the static instance or reset it to an initial state – before and after every test run (setup / tearDown).
So is the Singleton really so bad, should i never, ever use it?
Probably no other design pattern is / was adopted, loved, discussed and hated as much as the singleton.
No piece of software is the same, and there may be situations when a singleton may be the way to go. See the further reading link collections for more details and example patterns.
But – you must consider all the drawbacks and weigh if it’s worth to live with them!