Rehabilitating the Singleton Pattern
“Design Patterns: Elements of Reusable Object-Oriented Software”
came out in 1994 and it changed the software engineering landscape.
What made this book unique is that it wasn’t really based on code
(although it did contain a decent amount of it) but on terminology. It
picked up general ideas and concepts, captured them in diagrams and,
most importantly, gave them a name.
The power of names
Nobody had really thought about doing that before, and the idea was so good that even today, fifteen years later, most of these names are still in common use. You won’t come across a developer who has never heard about Singleton, a Visitor, a Factory or a Façade.
Of course, the science of software engineering has advanced quite a bit since 1994, and some of the concepts explained in the book came under attack. For example, we know a lot more about testing now, and this past decade has allowed us to identify techniques that make testing easier, and also anti-patterns that tend to get in the way of making our code testable.
Of all the design patterns from the book that have been criticized, none has taken as much of a beating as the Singleton. Not a day goes by without reading in blogs or irc that “Singletons are evil” and that you should avoid them at all costs. What’s surprising is that I read this coming from senior developers, and this statement tends to deeply puzzle more junior developers who suddenly find themselves having to rewrite a piece of code that they thought was quite natural and officially acknowledged as a good coding practice.
Here is the truth:
Singletons are fine as long as you don’t implement them with static |
Scoping it out
Let’s take a closer look at this statement.
Singletons are very natural entities in a software engineering. Regardless of the kind of code you write (front end, back end, embedded in a browser, running in a container, etc…), you will most likely need to talk to certain services that only need to exist as a single instance. It’s also no surprise that popular dependency injection frameworks such as Guice and Spring explicitly support the Singleton pattern.
Don’t feel bad for feeling the need to implement a certain concept as a Singleton, it’s perfectly natural.
So what’s wrong with statics?
There is ample documentation on the problems that static variables and methods (but mostly variables) cause, but in nutshell, they make testing and concurrency more challenging, and as such, they should be avoided. The main problem is that static defines a scope that’s even bigger than the application itself. It’s a state that will only disappear once the class that contains it gets unloaded, so frameworks have very little room to control its life cycle. Another way to look at it is that the static scope is beyond the reach of Java programs and lives in the realm of the JVM.
This is really the only problem. If we can find ways to have singletons that are more narrowly scoped, then the concerns I mentioned above disappear.
The next smaller scope to the one that static provides is instance: the value will remain live as long as someone is holding on to a reference to the object, but once that is no longer the case, this value is gone.
One way to improve on the static scope would be to create all your singletons in your main method and then pass them down to your application. With this change alone, you have suddenly made your entire application much easier to test and easier to reason about from a concurrent stand point.
Once you start going down that path, you start wondering if this “main” scope isn’t too broad. If a singleton you create in your main method is not needed until way further down the stack frames, maybe there is no point in exposing that singleton to your entire application. Is there any way that you could either create (ideal case) or at least expose (second best case) that singleton only to the section of your code that needs it?
This code structure also rises another question: it’s not exactly convenient to create a bunch of singletons in your main method and then pass them “down”. How do you do that, anyway? Ideally, you pass them as parameters to the methods you are calling, but that is not going to scale very well, never mind the fact that your method signatures are going to start looking like monsters. Updating your entire call chain whenever you need access to a new singleton is an absolute disaster since you will have to add this parameter to the signature of each method.
One way to mitigate this problem is to group all your singletons in one class called, say, Configuration, and only pass that class around. If ever you need one more singleton down the road, you just add it to this class and you don’t need to change any method signature. That’s better.
We are still exposing a lot of code to all these singletons, though, and even that uber Configuration parameter looks like extra weight on these methods (most of which might just pass them around and not even use them).
Injecting for fun and profit
This is where the @Inject annotation comes in. Initially popularized by Guice, this annotation ended up being promoted to a standard by JSR 330: “Dependency injection for Java“. I’m not going to go into details on how to use this annotation (check out Guice’s excellent documentation), but I’ll just limit my comments to the topic of this post, which is how to implement singletons properly.
Using @Inject to gain access to your singletons solves the following problems:
- No static.
- The creation of the singleton is externalized. You don’t need to worry how or where that singleton is created, you just need to specify that you need it.
- Finer scope. Only the class that you declare this injected field in will have access to that singleton. A side benefit of this is that you no longer need to pollute all your method signatures in order to pass this singleton all the way down the stack frames. It’s declared as a field and the dependency injection will automatically assign it at start up time.
- Finer granularity. You no longer need to pass a monster Configuration object that contains all your singletons around: just specify which singletons you need exactly.
This post is getting a bit long already so I’ll stop for now. There is much more to cover on the subject of singletons and, more broadly, of dependency injection, which I’ll try to cover in a future post.
In the meantime, let’s all agree to acknowledge that when implemented and used properly, the Singleton is a very useful design pattern.
From http://beust.com/weblog/2011/03/10/rehabilitating-the-singleton-pattern/
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)






Comments
Jose Maria Arranz replied on Fri, 2011/03/11 - 5:19am
Cedric, I like your article but you forget something, injection is not magical, to get dependencies injected the containing class MUST be also managed by Guice (or Spring).
Yes my class MyDBProcess may need some DataSource or similar singleton as attribute, and Guice (all of I will say is also applied to Spring or Weld) can inject it into my attribute avoiding de burden of constructor passing. The lifecycle of DataSource is clear, is a singleton, but what about MyDBProcess? The lifecycle of MyDBProcess has something to do with the lifecycleof DataSource? NO, absolutely no.
The problem arises when Guice need to CONTROL the lifecycle of MyDBProcess to get the DataSource injected :(
And because the lifecycle control is impossed by Guice I must to explain what lifecycle is to Guice, is a singleton?, is a "request" object?
Because humans are lazy "by default" then I define MyDBProcess as a singleton, then I have again a new singleton, and when I need to pass MyDBProcess to another class MyBusinessProcess then I think, umm MyDBProcess is already managed by Guice and so I can inject into other classes, why not is also MyBusinessProcess a singleton?
And finally you end doing singleton-based programming to avoid passing one or two true singleton objects. And when you do singleton-programming you usually say "goodbye" to object oriented programming, and the world is reduced to classes as a simple aggregator of attributes and methods, usually saying goodbye to encapsulation (attribute injection is more popular and set methods are recommended), implementation inheritance and so polymorphism.
Yes course, "prototype" scope is also an option, but most of the time when you need a prototyped object you create it when you need it, adding this prototype object as an attribute is not for me a good approach (just for a simple call you hold this object "for ever") and again to get this prototype object injected I must to explain to Guice the lifecycle of the container class... just for a simple use of a service object (the prototype). The alternative is using Guice as a Service Locator in many places, I'm not against this option really but I don't see very much gain instead of a manual/factory/service locator approach.
What is the solution?
In my opinion more bytecode enhancement.
Is simple, I code:
new MyDBProcess();
and DataSource gets automatically injected.
There are three options:
1) Compile time enhancement of classes: OK, in spite of is not ideal for me
2) Use a java-agent for the root ClassLoader: BAD, too hard
3) Use a special ClassLoader created in runtime to perform bytecode weaving: THE BEST OPTION
The 3) is possible because I've already done it before, but I don't find support in Spring, Guice and family for this option, if this option is possible IS FAR OF POPULAR AND PROMOTED by DI tools.
In summary: I need non-intrusive dependency-injection.
I don't want my code polluted with tons of IoC to avoid the problem of manual passing of two or three singletons, automatic DI resolution is good just in the adequate size.
I was recently shocked by this text of a prominent DI/IoC supporter guy:
Inversion of control is a common feature of frameworks, but it's something that comes at a price. It tends to be hard to understand and leads to problems when you are trying to debug. So on the whole I prefer to avoid it unless I need it. This isn't to say it's a bad thing, just that I think it needs to justify itself over the more straightforward alternative.
I don't believe in gurus, I just believe in technical reasons, but sometimes I've been feeling like the only one in the world thinking something similar until I've read this piece of cake XD
By the way, Cedric, I put you into the category of gurus and I must recognize the "said by Cedric B." influence :)
Dean Schulze replied on Fri, 2011/03/11 - 3:24pm
Mark Thornton replied on Sat, 2011/03/12 - 4:16am
Chance Gold replied on Sat, 2011/03/12 - 12:03pm
Robin Bygrave replied on Mon, 2011/03/14 - 3:17am
Well I disagree with the point about concurrency. Any concurrency issue with a "coded singleton" will also exist with any injected singleton/shared instance. In fact, probably the main reason to use singleton scope is to get access to shared objects that are relatively expensive to create (so you have to concern yourself with concurrency).
In regards to testing singletons - yes, they make it harder to test (well the static makes it harder to test) but you can effectively remove all the logic from the singleton. You can 'split' the singleton into 'scope' and 'behavior' and have the singleton instantiate it's behavior on initialization (i.e. make the behavior an interface and have the singleton instantiate an instance of that via properties file or whatever). The singleton provides the scope and always just proxies through to the behavior. That way you can always test the behavior and the singleton itself contains no actual logic (it only provides scope management).
I don't really like your arguments about monster configuration object being passed around. That is not required for a singleton in my book.
The benefit in see with @inject is that you can later change the scope to be something other than singleton without changing your code.
Oh well, that's my 2c - I always split the 'scope' from the 'behavior' if I code a 'singleton'.
Cheers, Rob.
Mark Thornton replied on Mon, 2011/03/14 - 9:06am
in response to:
Chance Gold
Witold Szczerba replied on Mon, 2011/03/14 - 5:55pm
in response to:
Chance Gold
Just use the Guice library in a standalone application and you have everything one needs - working with Guice feels like DI is integrated in the language. No need to introduce the public static masacre anymore.
Witold Szczerba replied on Mon, 2011/03/14 - 7:47pm
in response to:
Jose Maria Arranz
I am not sure I do see what is the problem you describe, is it about different life-cycle of objects? If so, this is not a problem.
You said you would like to be able to spread new MyDBProcess(); here and there in your code and you would like the DI container to step in and take over the creation process and inject required members. This approach, however, completly defeats one of the purpose of the Inversion of Control: the testability. How are you going to mock the new MyDBProcess()? There are, however, the alternatives to this. Guice's alternative is to injecting Provider<MyDBProcess> instead of the MyDBProces itself. Now, instead of writing: something = new MyDBProcess(); you write: something = dbProcessProvider.get() at anytime you want. This is very usefeful when you have some long-living object or service and inside it you want get injected something of shorter life. Advantages are that, looking at the object signature one can see what are the dependencies (no need to read every single line of code to figure it out) and you can still inject a mock when doing some tests.
You can read more about this here:
Dependency Injection Myth: Reference Passing by Miško Hevery
I strongly urge you to read this article, as it explains many anti-patterns relating DI, programmers drop in very often.
Jose Maria Arranz replied on Tue, 2011/03/15 - 11:57am
in response to:
Witold Szczerba
Witold the problem is simple: I DON'T want to give up control of "new" keyword, period.
A program can FULLY MOCKED if there is NO "new" in your code and ALL of your objects are:
1) Singleton
2) Prototype scoped (new instance when access it)
And maybe session scoped.
In this scenario the Service Locator pattern is used in all places, but in this case managed by the DI framework with a very high price: you must give up control of the lifecycle of ALL of your classes and to explain to the framework the lifecycle of EVERY class, EVERY object.
I'm sorry but I don't want ALL of my objects get controlled by a DI framework just to provide "extreme testing", I don't believe in "extreme testing" when everything can be mocked, this kind of code can be fully mocked right but the end result may be a poorly engineered architecture because DI frameworks invite you to simplify to the extreme the lifecycle of your objects (usually singletons) and you end with a singleton-programming approach.
Anybody has tons of utility/service classes too easy to get mocked, or the contrary, my MyDBProcess class may define very important business rules, these business rules only can be mocked by ... ITSELF!! :)
I don't want my MyDBProcess virally converted in a singleton just to hold a simple DataSource or similar singleton, and I don't want mock this critical object and because I don't believe in "extreme testing" where ALL classes and methods are directly tested ("extreme low level testing") or every class, critical or simple, must be mocked.
Chance Gold replied on Tue, 2011/03/15 - 1:36pm
Witold Szczerba replied on Tue, 2011/03/15 - 6:41pm
in response to:
Jose Maria Arranz
DI is not about extreme testing as you call it, but of course it makes unit testing easier. For me, the main gain of using this design pattern is that it's easy to follow the two very important principles:
In contrast to what you say, I believe that Inversion of Control by Dependency Injection is object-oriented programing's best companion, but - from my personal experience, I know it is quite easy to use it poorly and turn the design into the mess. The problem right now is that it is so easy to hear about DI and simultaneously so easy to mis-use it, because it is quite hard to find really good guidelines. Almost everything I have learned by reading Misko Hevery's (thanks man!) blog entries from 2008 and 2009. He turns everything around testing, testability, etc., but at the same time he reveals the secrets of first class DI and object-oriented design.
I do not judge you, but if you claim that the DI drives your code into procedural style - there definiteley must be something wrong with... I don't know... with something about the way you use it.
Jose Maria Arranz replied on Wed, 2011/03/16 - 2:04am
in response to:
Witold Szczerba
Witold I DO dependency injection most of the time "the old way", passing singletons in constructors. I would like automatic singleton injection in AOP as said before but it seems a bit hard.
I don't buy Cedric's argument of the problem of passing singletons again and again in many classes, not so in real world, in real world you have one root class holding the singleton (for instance a DataSource or similar db-singleton) and many other dependent classes just hold the parent class and ask this DataSource to the parent class when needed, in summary, just one parameter in constructor, the parent object.
I would like much more automatic dependecy injection whether it were not so intrusive, so viral.
Witold Szczerba replied on Wed, 2011/03/16 - 1:36pm
in response to:
Jose Maria Arranz
Why do you explicitly state singletons? DI is about injecting just any dependencies (best if direct dependencies), not just singletons. This is what different, also custom, scopes are for (including a no-scope).
Javin Paul replied on Sat, 2011/04/09 - 4:09am
in response to:
Dean Schulze
1) Lazy initialization
2) Early initialization
3) Serialization
4) Many ClassLoaders
5) Cloning
Thanks
Javin
Singleton Pattern in Java