More about Singleton and Constructor Injection

Wednesday, July 29, 2009 8:07 PM

So, I gave the first of my talks about Design Patterns last week.  I concentrated my attention on the Command and Singleton patterns.  My colleagues weren't particularly interested in the Command pattern, but my remarks on the Singleton pattern raised a lot of interest.  For many, it was the first time they'd really heard someone come out and say that static methods were a bad idea.  It was ironic that Max Pool was blogging about the uselessness of evangelism on modern programming techniques while I was having a positive experience doing exactly that.

The thing is, everyone is used to a certain way of doing things.  They know that using static methods and shared state take time.  They know that they always end up with dependency soup, but it's usually thought that this is just what programs are like.  To a certain extent, it's always going to be hard to eliminate externalities, but it's a lot easier than most people expect.

Constructor Injection, equally, is really easy to explain: you just pass things into the constructor.  Developers who write a lot of tests can instantly see the advantages of doing things that way.

None of this makes it easy to be the guy in the room saying the exact opposite of what most people expect, but it's very rewarding when it comes off.

Here's some talking points:

  • Business requirements change, they usually change in a way you're not expecting.
  • If you only need one instance, creating it in the Main method and passing it into the objects that need it is much more flexible than using a Singleton pattern.
  • If something is public, it will get used, you can't create a static method and then say that people shouldn't use it.  They will, and it'll be your fault.
  • Constructor Injection is a very low cost thing to implement when you're writing new code. 
  • Refactoring old code to use it is much harder, but that reflects the refactoring challenges inherent in Singleton-style code.
  • If you're passing a lot of objects down a function chain, that's a code smell.  Chances are that the "group of objects" is a good candidate for a class.  Once you understand what that class is actually called, you're on your way to a better design.
  • Passing lots of objects in constructor chains isn't as easy to deal with.  Dependency injection containers make this problem manageable.  (Amongst other things...)
  • Evaluating all of your dependencies up front can lead to problems with circular dependencies.  Usually the best way to deal with this is to redesign objects so that they don't have circular dependencies, but property injection can help in ugly cases.
  • Ironically, developers often spend a lot of time trying to think of the best way to make object interact, how to load configuration settings and so on.  Constructor Injection makes this simple: it's always in the constructor.
  • Constructor Injection isn't quite the end of the story.  If you actually need more than one object, we need to start talking about abstract factories.

The sooner you start using constructor injection, the sooner refactoring your code will stop feeling like playing Jenga.

Technorati Tags: Singleton,Inversion of Control,Abstract Factory

Comments
Gravatar
# re: More about Singleton and Constructor Injection
Posted by Emanuele Gherardini on 12/3/2009 11:23 AM
This is interesting, but (referring to the java world) I think it's quite unfeasible in certain situations: for example in stateless services exposed via stateles EJB's in which, for example, Singletons can be used to load only 1 time some configuration (from properties files or databases for example) and share them among all classes. Don't you think ?
Gravatar
# re: More about Singleton and Constructor Injection
Posted by Julian on 12/3/2009 11:36 PM
I think part of the problem is that stateless is one of those dishonest terms: configuration is, like it or not, part of state. Now, I know very little about EJB (last looked at it in depth about seven years ago and thought it looked like a complex solution to a simple non-problem) but can you seriously not specify constructor parameters to stateless/single use objects?

If you can't, my first thought would be that you're using a bad technology that encourages bad design practices. Spring.NET can definitely cope with this, so if EJB can't, it's J2EE's fault.

On the subject of the "configuration" class. I don't like them because they separate data from behaviour. A "configuration" often has more than one responsibility, and most of the responsibilities are actually those of abstract factories. Only we don't tend to make "configuration" classes abstract factories.

A "hack" way of dealing with a forced empty constructor would be to employ a singleton IoC container and expose everything as a proxy to the real object that the container created. I /really/ don't like this as a solution either.

In short, I agree with you that sometimes you can't do it, but I'd say that when you can't do it, it's because your architecture is wrong. The Java community has a fairly good track record as regards OOD (certainly better than Microsoft's: Alt.Net is tiny compared to the comparable Java grouping) but Sun's own record on design is... patchy. Sometimes they're brilliant... but things like Spring.NET were developed precisely because J2EE was the "wrong thing".

Anyway, thanks for your comment. I may work this into a proper post after I organize my thoughts on the subject further.
Gravatar
# re: More about Singleton and Constructor Injection
Posted by Emanuele Gherardini on 12/15/2009 4:03 PM
Thank you for answering to my comment. I hope to see your thoughts soon.
Something to add?

Talking sense? Talking rubbish? Something I'm missing? Let me know!

Fields denoted with a "*" are required.

 (will not be displayed)

 
Please add 3 and 5 and type the answer here:

Preview Your Comment