Recently I have published a post on “Static Vs Singleton“. While working on the topic, I slipped into another: “Are Singletons really that bad?”. I started reading further. Trust me, it’s a holy war! And here is the result of my investigation.
To start with let’s take a look of the definition of the pattern. Singleton as a pattern provides two functionality:
1. Global access to an object
2. Only one unique instance of the object across the system (in some cases, limited number of instances)
So, what is bad about Singleton? Why Singletons are so bad?
1. In a Singleton, we have a private static final instance of that class and we provide a public static getInstance() method to access that instance. This means that the instance can be accessed/used from any where under the Sun. A developer can use the instance within a method form any other class just by invoking the getInstance(). He is not bound to declare the dependency in the method signature as he is not explicitly passing that instance through the arguments. Does not this create unwanted dependency and close coupling? Yes, it does. The worst thing is ONLY the programmer who has created the dependency knows about it, but the user of the method who came later never notices it as the dependency is not explicitly mentioned. So, it is very easy to get a Singleton, use it and then forget it for the time being. Most of the programmers (including me :-)) goes on using it almost every where creating a hidden chain and finally cycle of dependencies. When the bubble bursts, its too late. Only option left is to refactor the code heavily. So, the first point – Singletons expose a global variables and global variables creates unwanted dependencies.
2. By this time it is clear that use of Singleton creates a very tight coupling between it (the Singleton) and user who uses it. This tight coupling makes it difficult to test the user alone. If I want to test the user, the Singleton has to be tested also (I have to first create the Singleton and then test the user – maintain a particular order). But, that ‘s not what I am supposed to do! Ideally the singleton should be passed in the user classes’ constructor as a parameter (or in the method as an argument in case a method is being tested). This way, the tester can easily make a mock of the Singleton and pass it as a parameter or argument.
3. Another accusation against the Singleton is that it violates the Single Responsibility Principle. A Singleton class holds the business logic as well as it’s own creation logic. But the SPR principle states that a class should have one and only one responsibility. To be strict enough, one of the responsibilities should be moved out of the Singleton class.
Point number two of Singleton definition doesn’t have a problem. There may be a number of real use cases where only one instance (or limited number of instances) across the system is required. But, the big question is can I have a single instance without exposing it globally? Dependency Injection is the answer. Let the Singleton be created during the initialization of the application and then pass that unique instance downwards (from the top layers to the bottom) as parameter/argument to all the objects those need it. The getInstance() method should be used ONLY when it is necessary. This is a much cleaner approach.
As per my understanding, the primary purpose of this pattern is to provide a system wide single instance. Global access is secondary. Otherwise, the name of this pattern might have been Globalton! Use it properly and ONLY when it is really needed. But finally, I believe avoiding it would be better than abusing it.