One of the most derided, yet most loved and used patterns is the singleton pattern. Its supporters continually praise its ability to limit instantiation of objects and its opponents continually chastise its tendency to be little more than a glorified global.
While programming in many ways boils down to a matter of preference (you can always find someone that agrees with you,) I thought I might as well document my opinion so that those who don’t care can have one more thing to ignore.
Details after the jump
First, what is the singleton? Most of us know what it is and for many of us I would guess it is the first pattern we grew to know and love. The official definition from the GoF’s book is as follows.
Ensure a class only has one instance and provide a global point of access to it. - Design Patterns: Elements of Reusable Object-Oriented Software.
The basic summary of why I think singletons are evil is summed up in the second half of its definition. It provides a "global point of access". Even people that say singletons are not evil tend to ignore the fact that this is a built in property of the pattern and some even go so far as to not realize that this is even mentioned in the official definition:
Singletons should be used to control creation, not access. A singleton should *not* be used as a global object just because you can. I find it hard to dismiss a pattern simply because some people don’t use it how it was intended to be used. - Matt Berther, Singletons are not evil
A large, defined purpose of the singleton is to provide a global point of access to an object. This cannot be argued.
So why is a single point of access a bad thing?
A single point of access is not in and of itself a bad thing. If you read the entirety of Matt Berther’s article, you would find that he is very clear that he does not believe you should use a singleton as a global just because you can. By "using it as a global" he is referring to the method of peppering your code with calls to MySingleton::getInstance(). It may be hard to see some of the initial similarities between the following snippets of code.
Don’t let the extra class name fool you. While it does indeed force that object to be of a particular class you will never have any clue by looking strictly at your method declaration of what the dependencies of the method are. This is one of the large problems with both globals and singletons: they mask your dependencies. This will without a doubt make your code less flexible and harder to understand. The lack of flexibility also makes your code harder to test and in the long run harder to maintain.
But the singleton pattern is so useful!
Of course singletons are useful. There are many things that are useful, but that doesn’t automatically make it a good idea.
I will admit, I have used singletons quite heavily in my past. The most common reasons that I would implement them are:
- You can only legitimately have one logical instance of a class
- The object is expensive to create
- You need primitive caching (sort of related to #2)
These are all legitimate reasons to use a singleton pattern. I would discourage the thought of using as a permanent solution for caching however. While it is useful for quick and dirty caching there are many more useful patterns and systems for doing this.
So if you take away caching then there are still two uses for the singleton. A responsible person does not tell you to not use something without offering an alternative. So here is my alternative:
Don’t use singletons…
That’s right, sage advice I know. If your software is designed properly you should still be able to centralize the object creation (that needs centralized) to ensure that you only are creating one instance of an object. If you need to control creation of it then use a factory to do so. Then pass the object to the methods that need it. This will allow you to make your dependencies much more explicit which will provide you with more flexibility in the long run. It will also allow you to unit test your code much more effectively.
Unless you have to!
There are some times you just cannot get away from singletons. In most cases the reason why is the amount of refactoring that it would involve. You simply do not have time for it. The singleton pattern is not all bad. I do think it is a viable pattern for object creation. So just don’t "take advantage" of the second half of its definition (global access.) Get rid of all the getInstance() calls. Those are the real problem with singletons anyways. Move them as high in your call chain as you possibly can. Then you get the benefits of NOT using the singleton without having to embark on a massive rewrite of code.
I bid you farewell
Ultimately, programming is a matter of preference. So long as you are achieving easy to understand and therefore easy to maintain code. It doesn’t honestly matter much how you do it. I personally do not see very many viable uses for singletons and I know there are many people that agree with me (google evil singletons). It’s simplicity seems appealing, but they are incredibly easy to use in a damaging way. This is the danger you risk with any concept that is easy to understand and easy to abuse.