Daniel is a handsome Java Developer in Brisbane, Australia. Twitter: @danielalexiuc Daniel has posted 3 posts at DZone. View Full User Profile

Dependency Injection Makes Your Code Worse

10.25.2009
| 20309 views |
  • submit to reddit

"Dependency Injection" - you've probably heard and uttered this phrase so many times that it has become almost meaningless now. But just humour me for a moment. Say it slowly to yourself and imagine you are hearing this phrase for the first time.

It sounds insidious doesn't it?

If you went to the doctor and he told you he was going to give you a "dependency injection", then you would probably think there was something seriously wrong. If you were to buy a house, and the seller told you he wanted to inject a few more dependencies into the contract - would that sound good to you?

There is not much to like about either of those two words: "dependency" and "injection".

And it is the same thing with programming. Dependencies are not good, they are bad! They should be things that we try to avoid wherever possible. We spout principles like "loose coupling" and "high cohesion" to make people think that our code is structured and organised. But far from improving our code by being a way to structure and organise it, "dependency injection" actually makes it worse.

Questions worth considering

How can you possibly reason logically about what a method or class does when dependencies are being squirted in all over the place?

How could a system that facilitates the adding of dependencies to your classes possibly be beneficial? Especially when those dependencies are being managed by a "dependency injection framework" and you don't even know for sure what those dependencies will be?

A symptom of a larger problem

Most Java code I have seen (and written myself) is a gallimaufry of frameworks, patterns and objects that obscure meaningful code.

Dependency injection may have been developed as an attempt to solve some of these problems, but fundamentally it is adding to the problems. It is yet another framework to add to the tangled mess of code that allows you to abstract any real meaning further away and which enables your methods and classes to behave in more and more unpredictable ways.

My real gripe, though, is not with Dependency Injection. Dependency Injection is just a symptom (albeit a very obvious one) of the real problem facing Java programmers: the object-oriented paradigm.

Deep down you know it

There are other obvious symptoms that we are doing things the wrong way. Can you put your hand on your heart and honestly say that you are happy and productive with Dependency Management frameworks like Maven, and ORM frameworks like Hibernate? Or are they something that you spend way too many billable hours fiddling with?

The object-oriented paradigm has encouraged a generation of programmers (myself included) to write code in the most abstract, meaningless and side-effecting way possible. And even though we don't really use Java in an object-oriented way anymore (because deep down we know it just doesn't fundamentally make any sense), that same paradigm has taught us to write code that cannot be relied upon.

It cannot be relied upon because data is being twisted and untwisted into objects, those objects are being bombarded with dependencies, and those dependencies are recursively being infected by other dependencies.
Published at DZone with permission of its author, Daniel Alexiuc.

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

Comments

Liam Knox replied on Mon, 2009/10/26 - 7:59pm

I cant really say I agree with much in this article. I think if you want to write robust, maintainable and extensible code these days you first think of basic components, how they interact and importanly how you can unit test this.

This test driven methodology naturally aligns itself to IoC and you do end up with good code, that is if you are able to write good code in the first place. For specifics just try using Springs Unit test integration and Mockito.

I can more sympathise with the authors views on ORM as this is really a hack for the 'round peg square hole' problem that is unsolveable.

Jerwin Louise Uy replied on Mon, 2009/10/26 - 8:44pm

Too much indirection in DI makes code really unreadable especially when the boundary conditions, contracts and assumptions are not expressed clearly. Of course, one of the side effects of using a DI framework is that you have more fine-grained objects. Therefore, each class performs a specialized role/responsibility that makes life easier when isolating side effects. The goal of DI is to make code maintenance a lot easier with the assumption that dependencies and their corresponding boundaries are defined. If some of the responsibilities leak, then using a DI framework becomes a nightmare. Just imagine maintaining code that has at least 5 xml configuration files and overrides.

Mark Unknown replied on Mon, 2009/10/26 - 8:49pm in response to: Harshal Vaidya

"Despite having years of experience with Hibernate and numerous tools to automate all that hbm file creations and mapping object creations we continue to waste long long hours in tracking down many many excpetions which otherwise wouldn't have been a problem at all if we ended up using simple spring-jdbc."

 In most projects, this is a "pay now"  or "pay more later" scenario.  If you take the time to learn Hibernate (or another good ORM) it will pay dividends in the long run.  Is this 100% true? No. But it is pretty much on every project that I have worked on.  The same holds true for Spring (or any other good DI api).

Henk De Boer replied on Tue, 2009/10/27 - 4:02am in response to: Jordan Zimmerman

Oh, but you will care when you have to update the code someday. Remember your post when you're scratching your head in vain trying to figure out the actual instance of the interface that's being used and the original writers are long gone from the team

 

C'mon, have you ever been in that exact situation you're describing now? I guess you haven't, since the solution to your supposedly hard problem (scratching my head?) is actually extremely simple.

Let me make myself clear, IF I needed to know the implementation of an injected dependency, for instance because it's not behaving well (let's say a CustomerDAO that returns the wrong Customer), THEN I use two simple little tricks:

  1. Right click the Interface type of the dependency, select 'show type hierarchy', navigate to the obvious one. Inspect its code.
  2. In case it's not 100% clear what the obvious implementation is following method 1., I simply put a break-point on the line where the dependency gets injected. When the break-point hits, I look at the variables in scope and voila... the complete and exact implementation type will be revealed to me.

Yannick Loth replied on Tue, 2009/10/27 - 8:35am

I agree to this post and add my reflexions to this in an answer to this post on my blog.

You may read it here.

Josh Marotti replied on Tue, 2009/10/27 - 12:18pm

I see where you are going, but if you make dependency injection with constructor arguments instead of property accessors, you'll find that adding and removing spring from an application doesn't change the code AT ALL.

Jordan Zimmerman replied on Tue, 2009/10/27 - 1:57pm in response to: Henk De Boer

"C'mon, have you ever been in that exact situation you're describing now? I guess you haven't, since the solution to your supposedly hard problem (scratching my head?) is actually extremely simple."

Yes, I have. However, re-reading my post I wasn't totally clear. The main problem I ran into was when I was working with Apache Shindig which uses Guice in a deep way. I would come across instances of interfaces and it was nearly impossible to determine where they were "wired" together. Usually, I'd have to a full source grep. Once I'd found the concrete class, trying to override behavior was a nightmare. I'd make my modifications then have to build (using G*damn Maven) the entire thing and run only to find out I'd made some kind of mistake. The errors displayed from Guice were rarely helpful in discovering the problem.

 

Aziz Kadhi replied on Tue, 2009/10/27 - 2:45pm in response to: Fab Mars

+1. Very well said, exactly what I was thinking about. Different challenges require different solutions.

Aziz

Comment viewing options

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