Monday, 20 July 2015

Difference between Dependency Injection and Factory Pattern in Java

TL;DR Main difference between dependency injection and factory pattern is that in case of former dependency is provided by third party (framework or container) while in case of later dependency is acquired by client class itself. Another key difference between them is that use of dependency injection result in loosely coupled design but use of factory pattern create tight coupling between factory and classes which are dependent on product created by factory. Though both Dependency Injection and Factory pattern looks similar in a sense that both creates instance of a class, and also promotes interface driven programming rather than hard coding implementation class; But, there are some subtle differences between Factory pattern and dependency injection pattern. In case of factory design pattern, client class is responsible for calling getInstance() of factory class to create instance of products, it also means that client class is directly coupled with factory and can't be unit tested without factory class being available. On the other hand in Dependency Injection, client class has no clue about how his dependencies are created and managed. It only knows about dependencies. Mostly dependencies are injected by framework e.g. bean class exists without any hard coded dependency, as those are injected by IOC container e.g. Spring. You can also used points used here to answer questions like difference between Spring IOC and Factory pattern because Spring IOC is nothing but an implementation of dependency injection pattern. BTW, if you are serious about learning design patterns and principles, I suggest you to take a look at Head First Object Oriented Analysis and design book. This book is overshadowed by its popular cousin Head First Design Pattern but its one of the book to master object oriented design principles and patterns.




Factory Pattern vs Dependency Injection

To understand difference between factory pattern and dependency injection better let's see examples of how both DI and Factory design pattern are used :

In Factory Pattern

public class CashRegister {

    private PriceCalculator calculator = PriceCalculatorFactory.getInstance();

    public void add(Transaction tx) {
          int price = calcualtor.getPrice(tx);
          add(price);
    }

}

In this case dependent class, CashRegister is directly coupled with PriceCalculatorFactory because its calling static getInstance() method from PriceCalculatorFactory to satisfy its dependency. In order to test CashRegister, you must need a PriceCalculatorFactory, which is not good for unit testing of this class. On the other hand, if you use Dependency injection, then dependencies are added by framework e.g. Spring framework or DI container like Google Guice because you reverse the responsibility of acquiring dependencies. Now it's responsibility of IOC container to inject dependency than the dependent class fending for himself. In case of dependency injection any class just looks like a POJO.

In Dependency Injection 

public class CashRegister {

    private PriceCalculator calculator;

    public CashRegister(PriceCalculator calculator){
        this.calculator = calculator;
    }

    public void add(Transaction tx) {
          int price = calcualtor.getPrice(tx);
          add(price);
    }

    public void setCalcuator(PriceCalculator calc){
        this.calculator = calc;
    }

}

You can see that dependency for CashRegister, which is PriceCalculator is supplied via constructor, this is known as constructor dependency injection. There is other form of DI as well e.g. setter injection, in which dependency is provided using setter method. For example, setCalcuator(PriceCalcuator) is facilitating setter injection there. You should use constructor injection to inject mandatory dependencies and setter injection for optional, good to have dependencies. You can also see when to use Setter vs Constructor injection for more guidelines.


Difference between Factory Pattern vs Dependency Injection

Based upon our knowledge of both of these patterns, you can easily deduce following key differences between them :

1) Factory pattern adds coupling between object, factory and dependency. Object not only needs dependent object to work properly but also a Factory object. While in case of dependency injection, Object just know the dependency, it doesn't know anything about container or factory


2) As compared to Factory pattern, Dependency injection makes unit testing easier. If you use factory pattern, you need to create the object you want to test, the factory and the dependent object, ofcourse you factor can return mock object, but you need all this just to start with unit testing. On the other hand, if you use dependency injection, you just need to mock the dependency and inject into object you want to test, no clutter or boiler plate is needed.


3) Dependency injection is more flexible than factory pattern. You can even switch to different DI framework e.g. Spring IOC or Google Guice.


4) One of the drawback of Dependency injection as compared to Factory pattern is that you need a container and configuration to inject dependency, which is not required if you use factory design pattern. In true sense, its not such a bad thing because you have one place to see dependency of your class and you can control them, but yes when you compare DI to factory method, this is the additional step you need to do.


5) Due to low coupling, DI results in much cleaner co than factory pattern. Your object looks like POJO and you also come to know what is mandatory and what is option by looking which type of dependency injection your class is using. If an object is injected using Setter injection, which means its optional and can be injected in any time, while dependencies which are injected using constructor injection means they are mandatory and must be supplied in the order they are declared.


6) Another tricky scenario with using DI is creating an object with too many dependency and worse if those are injected using constructor injection. Those co becomes difficult to read. One solution of those problem is to use Facade pattern and inject dependencies by encapsulating in another object. For example, you can introduce an object say ApplicationSettings which can contain DBSetting, FileSetting and other configuration settings required by object.


7) You should use Dependency Injection Patterns to introduce loose coupling. Use Factory Patterns if you need to delegate the creation of objects. In short, dependency injection frees your application from factory pattern boiler plate code. All the work which is required to implement a factory is already done by IOC containers like Spring and Google Guice.


That's all between difference between Factory design pattern and dependency injection in Java. Both patterns, takes out the creation of dependencies from dependent class, and encourages use of interfaces for defining property e.g. here we are using PriceCalculator which is an interface, so that it can later be replaced by any suitable implementation without affecting any part of code. Difference between factory and dependency injection lies on the fact that in case of factory, your dependent class is still dependent on factory, which is a new form of dependency, while DI takes out the dependency completely. Which means dependency injection provides better decoupling and unit testing of classes over Factory design pattern.

Difference between Factory pattern and dependency injection
If you like this article and interested to learn more about design patterns and principles, you may like following ones as well :
  • What is difference between Adapter, Decorator and Proxy design patterns? (answer)
  • How to implement Builder design Pattern in Java? (solution)
  • 10 Object Oriented Design Principle Every Programmer Should know (principles)
  • What is Open Closed design Principle in OOP? (answer)
  • What is difference between Factory and Abstract Factory design Patterns? (answer)
  • 5 Reasons to use Composition in place of Inheritance in Java? (answer)
  • How to implement Strategy Design Pattern using Java Enum? (solution)
  • What is difference between State and Strategy Pattern in Java? (answer)
  • Top 5 Books to Learn Design Patterns and Principles (books)
  • How to implement DAO design Pattern in Java? (answer)
  • Why implementing Singleton using Enum is better than Class in Java? (answer)
  • What is difference between Association, Aggregation and Composition in OOP? (answer)
  • Difference between Singleton and Static Class in Java? (answer)
  • Why you should Interface for Coding in Java? (answer)
  • Real life example of Decorator Pattern in Java? (example)

Recommended books for further reading on design patterns for Java developers 

  • Head First Design Pattern by Kathy Sierra (check here)
  • Refactoring, Improving design of existing code (check here)
  • Head First Object-Oriented Analysis and design (check here)

No comments:

Post a Comment