I’ve been fighting the fight against the Singleton pattern on a new code base and got me thinking about easy it is for developers to equate Singleton with Single Instance and, in my experience, more often than not, all they really want is a Single Instance. Of course, you may have proper uses for the Singleton pattern (all listed in the Gang of Four book I’m sure) yet there are many reasons why you should default to Single Instance.
Singletons often tend to be a pain because their “singleness” often makes testing a pain, with shared state persistent across different tests, and additional code to “reset” it. Worse still is the way that their global state makes them just a little bit too easy to stick into the middle of a block of code, without regard of whether or not it belongs. It often takes a while to unwind any dependencies and identify appropriate responsibilities. It’s global nature also often makes it all too tempting for it to evolve into a bit of the god object.
Robert Martin has a nice article on this: http://butunclebob.com/ArticleS.UncleBob.SingletonVsJustCreateOne
Probably the biggest problem with Singleton is the way it’s traditionally implemented in Java – as a static (member or method) that clients can just reach out and touch.
It’s important with Singleton to treat the object – once it has been made – like any other object. That is, you pass it around or inject it like any other dependency. This reinforces the fact that Singleton is a creational pattern, not an access pattern.
To spin it another way – properly built, the client should not be able to distinguish a Singleton from any other object built by a FactoryMethod. This in turn should mean that,in your tests, you can swap out the singleton for a customised instance.
I wrote a fairly longish post a few years back on this – http://twasink.net/blog/2004/09/creational-vs-access-patterns-and-other-diversions/
Well, yes, the global point of access is one of the two main problems. And actually, I remember it being part of the intent of the pattern.
The other main problem, in my opinion, is that the singletoness most often is, in fact, not really a property of the class, but just a property of the class as used in the current system. Encoding the knowledge of the singletoness inside the class itself (instead of elsewhere in the system) makes it harder to reuse than necessary.
And once you remove the global access point, and move the responsibility for caring that there is only one instance outside the class, it’s no longer a Singleton – it’s Robert Martin’s “Just Create One”.
Hi Ilja,
Thanks for your comment. I did enjoy reading that article!