Dependency Injection Principle

Suppose there are two classes - A.java and B.java where A.java consumes B.java as below-
class A{
   B b = new B();

The above code shows that the two classes are tightly coupled and hence have following drawback-

  • In case class A wishes to switch to another class instead of B, say class C then we need to make changes in class A which is not desireable.
  • If A is further inherited by other classes, then change mentioned in point 1 will affect ALL the child classes. 
  • Testing of class A will be difficult because its directly using B hence, mocking of class B is not possible. 
One solution to above problem is -
   class A{
      B b;
   }

But here, we are asking the calling class to initialize class B for A, which is not a good practise. Also, it still holds above concerns.

The above issue is resolved by 'Dependency Injection Princple' which states that - Two classes should be loosely coupled. This can be achieved by an interface or abstract class defining contract between the two.

That means,

interface Binterface {
}

class B implements Binterface {
}

class A {
   Binterface binterface;
}

Because of the above principle,
  1. Interface defines contract between consumer class and its child.
  2. Consumer class A relies on interface/adapter class to consume concrete class.
  3. This allows consumer class A to consume any class of type Binterface
  4. The consumer class A do not initialise the consumed class B, this leads to 'separation of concern'
  5. Also, we can easily mock the consumed class B and test the Consumer class A.
  6. And Class A can consume any class of type Binterface.
The only disadvantage of this principle is -
      As the class to be injected in consumer class happens in runtime, it wont give any compile time error.



Comments

Popular posts from this blog

@Overrride annotation introduced in Java1.5

Liskov Substitution Principle (LSP)

Interface Segregation Principle