Showing posts with label spring framework. Show all posts
Showing posts with label spring framework. Show all posts

Sunday, January 12, 2014

Dependency Injection Vs. Factory pattern.

Dependency Injection ( DI ) and Factory pattern might look related to each other but there is a difference between them . Factory take the responsibility of creating an object while DI inverse the process of how an object obtains the dependencies . DI gives the responsibility of injecting dependencies to an external entity.

Example : 

1. While using a factory , the dependent class  Foo is responsible for creating the instance of its dependency Bar  . In the below example we can see that Foo is calling the static method ( getInstance() )  of class BarFactory for instantiating Bar. 


public class Foo {
    private Bar bar = BarFactory.getInstance();

    public void doStuff() {
          bar.doSomething();
    }
}


2. With DI , Foo is no more responsible for resolving the dependencies by its own . An external entity , for example spring container is responsible for instantiating and injecting the instance Bar in Foo class . 


public class Foo {
  private Bar bar;

 /**
  * DI container uses the constructor to inject 
  * the dependency in Foo class.
  */
  public Foo(Bar bar) {
     this.bar = bar;
  }

  public void doStuff() {
      bar.doSomething();
  }
}

Advantages of DI :

1. Better decoupling of classes . 
2. Better Unit testing . Now it is easier to inject mock implementation of the services into the object being tested.

Dependency Injection with Spring framework


Dependency Injection means inversion of responsibilities with regard to how an object obtains references to collaborating objects. When applying DI , objects are given their dependencies at creation time by some external entity that coordinates with each object in the system.

As you can see,  this process is inverse of what happens without DI .  The object itself is responsible for instantiating or locating the dependencies by using direct construction of classes  or a service locator .


Interface injection 
In Interface injection , class provides an interface that its users implements to get the dependencies at runtime .                                                                                      
Setter injection  
In setter injection , setter method of the dependent class is used by a framework to inject the dependencies .                                                                                                  
Constructor injection 
In this , the constructor of the dependent class is invoked by the framework to inject the dependencies . 

1. Cleaner code / better decoupling :
The code is cleaner and  decoupling is more effective  between the classes . With DI , the objects are no more responsible for acquiring their dependencies by their own .

2. Efficient Unit testing :
With DI , it is easier to inject mock implementations of a service into the object being tested.

I did a google search and found some interesting links that describes the benefits of DI :




DI with Spring framework.                            

In Spring DI exists in two variants :
1. Constructor-based DI.
2. Setter-based DI.

1. Constructor-based DI.
In constructor-based DI , the constructor of the dependent class is invoked by the spring container . Each argument of the constructor represents the dependency. 

public class Foo {
 private final Bar bar;

 public Foo(Bar bar) {
  this.bar = bar;
 }

}
For injecting Bar into Foo's constructor , we need to define their dependency in a configuration file as given below :
<beans>
 <bean id="bar" class="com.springdi.Bar"/>
 <bean id="foo" class="com.springdi.Foo">
  <constructor-arg ref="bar"/>
 </bean> 
</beans>





2. Setter-based DI.
In setter-based DI , container calls the setter methods on the bean . Container  invokes the no argument constructor or no argument static factory method to instantiate the bean .

public class Foo {
 private Bar bar;

 /**
 Bean contains a setter method that will be invoked by the container
 to inject the dependency.
 */
 public void setBar(Bar bar) {
  this.bar = bar;
 }
}
In the configuration file , we will define the dependency using the tag "property" and not "constructor-arg".
<beans>
 <bean id="bar" class="com.springdi.Bar"/>
 <bean id="foo" class="com.springdi.Foo">
  <property name="bar" ref="bar"/>
 </bean> 
</beans>
Constructor-based DI or Setter-based DI 
For mandatory dependencies , use constructor-based DI and  for optional dependencies , use setter-based DI .  

NOTE :
If we use @Required annotation with a setter , it becomes a required dependency .