Java Design Patterns – Using Dependency Injection with the Factory Pattern

dependency-injectiondesign-patternsjava

Consider a module that is responsible for parsing files of any given type. I am thinking of using the strategy pattern to tackle this problem as I have already explained over here. Please refer to the linked post before proceeding with this question.

Consider class B that needs the contents of the product.xml file. This class will need to instantiate the appropriate concrete implementer of the Parser interface to parse the XML file. I can delegate the instantiation of the appropriate concrete implementer to a Factory such that class B "has-a" Factory. However, class B will then "depend" on a Factory for instantiating the concrete implementer. This means that the constructor or a setter method in class B will need to be passed the Factory.

Therefore, the Factory and class B that needs to parse a file will be tightly coupled with each other. I understand that I may be completely wrong about whatever I have explained so far. I would like to know whether I can use dependency injection in a scenario where the dependency to be injected is a Factory and what would be the right way to implement this so I can take advantage of areas such as mocking the Factory in my unit tests.

Best Answer

The right way to do this is to depend on an interface, and then inject an implementation of that interface into Class B.

An interface is just about the thinnest thing that you can depend on -- I liken it to trying to grab a wisp of smoke. Code has to couple to something or else it won't do anything, but coupling to an interface is about as decoupled as you can get, yet interfaces can provide all the functionality that you could want.

So have Class B's constructor take an interface to the class it needs, and have the factory produce that class as an implementer of the interface. Don't depend on the factory, depend on the interface, and have the factory provide an implementation of that factory.

So yes, you will be using dependency injection, but there's nothing wrong with that. Dependency injection -- particularly simple constructor injection -- should be the "normal" way of doing things. Simply put off new-ing things as far back in your app (and as close to the first line of main) as possible, and hide the new call in a class designed specifically for creating things.

Bottom line: Don't be hesitant to inject dependencies. That should be the normal way of doing things.