I am a software engineer at Google on the Android project and the creator of the Java testing framework TestNG. When I'm not updating this weblog with various software-related posts or speaking at conferences, I am busy snowboarding, playing squash, tennis, golf or volleyball or scuba diving. Cedric is a DZone MVB and is not an employee of DZone and has posted 90 posts at DZone. You can read more from them at their website. View Full User Profile

Rehabilitating the Singleton Pattern

03.11.2011
| 7896 views |
  • submit to reddit

“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/

Published at DZone with permission of Cedric Beust, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

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

Another problem with Singletons that isn't always appreciated is that they are only Singletons within the same class loader. The problems with Singletons in a cluster are evident, but your Singleton can have multiple instances within the same JVM if your application or framework uses multiple class loaders.

Mark Thornton replied on Sat, 2011/03/12 - 4:16am

So what should a general library writer do when faced with the need for a singleton? The static field has problems, but there all too many not quite compatible frameworks providing 'solutions'.

Chance Gold replied on Sat, 2011/03/12 - 12:03pm

I think it's too bad that @Inject wasn't added to JSE and handled by the JVM instead of added to JEE and handled by the container. That was a political decision no doubt as getting anything into JSE takes years and tons of debate. Anyway most of us are using JEE and @Inject is an excellent solution for wiring natural singletons such as services and resources into the application.

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

Having either the JVM or perhaps a ThreadGroup act as a default container for non JEE applications and supporting @Inject might have helped. As it is, for libraries which must work in non JEE contexts, the old static variable is still the only thing on offer.

Witold Szczerba replied on Mon, 2011/03/14 - 5:55pm in response to: Chance Gold

I think it's too bad that @Inject wasn't added to JSE and handled by the JVM instead of added to JEE and handled by the container.

Having either the JVM or perhaps a ThreadGroup act as a default container for non JEE applications and supporting @Inject might have helped. As it is, for libraries which must work in non JEE contexts, the old static variable is still the only thing on offer. 

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

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).

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

You ask yourself a very simple question: Is this object a natural singleton? Most resources and services are. I am THRILLED to give up the new keyword. How do I know when to new the object? The runtime (be it a virtual machine, container, provider, or whatever) charged specifically with managing these intances, can new the object exactly when it is first needed by the first piece of code that refereces it, or when a new session or request is created. More importantly, I don't need to pass handles to the object through ignorant constructors all over my code to get it everywhere it needs to go. Dependency Injection allows for seperation of concerns (and yes you can do it with annotated java code) which just makes so much sense.

Witold Szczerba replied on Tue, 2011/03/15 - 6:41pm in response to: Jose Maria Arranz

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.

 

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

Witold I DO dependency injection most of the time "the old way", passing singletons in constructors.

 

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

you are right but we need to consider following points While writing Singleton class :
1) Lazy initialization
2) Early initialization
3) Serialization
4) Many ClassLoaders
5) Cloning

Thanks
Javin
Singleton Pattern in Java

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.