Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Effective Java item 1 applicability with TDD and dependency injection

I have been reading Effective Java and I have some concerns regarding the first Item "use static factory method instead of constructor" in relation to TDD and dependency injection.

The item says that you should avoid having public/protected/default constructor and expose it using static factory. I agree with all the advantages related to using static factories like factories can have name, you can return subtype, you can reduce verbosity etc. But, I think in disadvantages Joshua missed TDD because having static factories in your code will lead to tight coupling and you can't mock the class using it. We will not be able to mock the class which will be having static factories. So, it hampers test driven development.

Second point, I think he missed that in todays enterprise development most of the applications use one or another dependency injection container. So, when we can inject dependencies using DI so why should I use it.

Please explain how it applies to today's Java enterprise development which includes DI and TDD.

like image 570
Shekhar Avatar asked Jun 25 '10 10:06

Shekhar


2 Answers

The DI engine is the factory.

Joshua Bloch understands DI well enough. I think this is an artifact of history, because DI's ascent came after the first edition of "Effective Java".

"Effective Java" was published in 2001. Martin Fowler coined the term in 2004. Spring's 1.0 release came in March 2004.

Joshua Bloch didn't modify that chapter for the second edition.

The point is the coupling that "new" introduces. Anyone who understands that and factories will easily make the leap to DI engines. The point is that his statements regarding "new", and the remedy of using factories, is still true.

like image 157
duffymo Avatar answered Oct 28 '22 23:10

duffymo


I see 2 separate issues here :

  • static factories vs using new()
  • dependency injection

When using new your code is just as tightly coupled as using a static method, actually even worse since the static factory can do some magic and return some specific implementation as long as it is a subclass or implementation of an interface.

With dependency injection the principle is also called the Hollywood Principle : "Do not call us, we'll call you". So in that philosphy you should not call new() or the static factory in your code, but have an external thing do that for you, either the DI framework or the unit test. This has nothing to do with factories or the use of new, as that is done somewhere else.

In that case factories are better because you can inject a test factory under your control. With new this is not possible (without doing weird things to the classpath like hiding the implementation with dummy objects in the test classpath, which I do not recommend btw).

like image 33
Peter Tillemans Avatar answered Oct 29 '22 00:10

Peter Tillemans