Dependency Inversion

Dependency Inversion

Dependency ingestion is ‘D’ in the SOLID design principle. It is a guideline that helps design loosely coupled classes. This principle states that High-level classes should not depend upon the concrete implementation of low-level classes. Both should depend on abstractions (ex Interfaces).

Dependency injection is the implementation technique to achieve Dependency Inversion. There are a couple of ways through them we can achieve these:

1.???Constructor injection

2.???Field injection

3.???Parameter injection

?Let’s take an example to understand why we need DI.

Consider 3 different animals like Cat, Dog, Horse that makes different types of noises.

interface SoundBehaviour {
??? void makeNoise();
}

class DogBehaviour implements SoundBehaviour {
??? @Override
??? public void makeNoise() {
??????? System.out.println("dog noise...");
??? }
}

class CatBehaviour implements SoundBehaviour {
??? @Override
??? public void makeNoise() {
??????? System.out.println("Cat noise...");
??? }
}

class HorseBehaviour implements SoundBehaviour {
??? @Override
??? public void makeNoise() {
??????? System.out.println("Horse noise...");
??? }
}        

If we now add this behavior in their specific animal classes then we are defining concrete implementation in the individual classes.


public interface Animal {
??? void makeNoise();
}

class Cat implements Animal {
??? private CatBehaviour catBehaviour = new CatBehaviour();

??? @Override
??? public void makeNoise() {
??????? catBehaviour.makeNoise();
??? }
}

class Dog implements Animal {
??? private DogBehaviour dogBehaviour = new DogBehaviour();

??? @Override
??? public void makeNoise() {
??????? dogBehaviour.makeNoise();
??? }
}

class Horse implements Animal {
??? private HorseBehaviour horseBehaviour = new HorseBehaviour();

??? @Override
??? public void makeNoise() {
??????? horseBehaviour.makeNoise();
??? }
}?        

In the above example, Animal is a high-level class and SoundBehaviour is a low-level class. In this approach following are the issues observed:

  • High-level classes are dependent upon the low-level classes implementation that makes them tightly coupled.
  • We are promoting inheritance that may have some side effects
  • Unit testing is very difficult

?So in such scenarios, DI principle helps us out. This principle states that High-level classes should depend upon low classes through abstraction only.

We can use dependency injection here to make classes lose coupled.


class Animal {
??? private SoundBehaviour soundBehaviour;

??? public Animal(SoundBehaviour soundBehaviour) {
??????? this.soundBehaviour = soundBehaviour;
??? }


??? public void makeNoise() {
??????? soundBehaviour.makeNoise();
??? }
}        

Then we can instantiate Animal class with any required behavior and the animal objects will start behaving like that.

Animal dog = new Animal(new DogBehaviour());
Animal cat = new Animal(new CatBehaviour());

dog.makeNoise();

cat.makeNoise();        

?The advantage of doing this is as follow:

  • ?High-level classes (Animal) is now depending upon low-level class abstraction
  • Unit test cases are easy now (just mock the object, you can get the required behavior)
  • Composition is used instead of inheritance
  • By doing this, we are now can change the behavior at run time without making any changes in code.

So, as we can see using DI, we can design a system less couple for each other.

要查看或添加评论,请登录

Tushar Goel的更多文章

  • DB Isolation Levels Part -2 (Repeatable Read and Serializable)

    DB Isolation Levels Part -2 (Repeatable Read and Serializable)

    In the last article, we learned about Read un-committed and Read committed isolation levels and the problems linked…

  • DB Isolation Levels in Detail - Part -1

    DB Isolation Levels in Detail - Part -1

    If two transactions don't touch the same data, they can safely run in parallel because they are not dependent on each…

    1 条评论
  • How Kafka is so efficient?

    How Kafka is so efficient?

    What is Apache Kafka? Apache Kafka is a distributed streaming platform that allows you to:: Publish and subscribe to…

  • Law of Demeter (Principle of least knowledge)

    Law of Demeter (Principle of least knowledge)

    In the last article we have discussed Tell, Don’t ask guideline. In this article, we will discuss another guideline…

  • Tell, Don't ask!

    Tell, Don't ask!

    Few days back I was having a discussion with one of my friends and we were discussing how to reduce coupling between…

  • Concurrency Pattern: Active object pattern

    Concurrency Pattern: Active object pattern

    This pattern is a type of concurrency design pattern and widely used in applications. Also, it is used to create…

  • JavaScript: DOM Manipulation

    JavaScript: DOM Manipulation

    In this article, I will explain how to do DOM manipulation using pure JavaScript. We have many other libraries…

  • The JavaScript EventLoop

    The JavaScript EventLoop

    This post will explain one of the most important concepts of JavaScript i.e.

  • How to use an index in MongoDB?

    How to use an index in MongoDB?

    In this post, I will explain how to use an index in MongoDB. In an earlier article, I explained how indexes work.

    3 条评论

社区洞察