DEV Community

Adam Roynon
Adam Roynon

Posted on

Dependency Inversion Principle

The Dependency Inversion Principle is a component of The SOLID Principles. These principles set out simple rules to follow that allow us to create maintainable and easily extensible codebases. The dependency inversion principle states that any entity should depend on abstractions rather than concrete implementations. This basically means that when you have one class that is dependent on another class it should use polymorphism to depend on an abstracted interface rather than the concrete implementation of the class. This allows you to easily swap out concrete implementations without having to refactor all dependent classes.

The below code snippet shows an interface called 'UserRepository'. We are going to use this interface to create subclasses that handle users in our database. This is a common approach as it allows you to create multiple child classes for different databases or storage mediums. For example, we could have one child for a SQL database and another for an in-memory database.

public interface UserRepository {

  User findUserById(long id);
  boolean createUser(User user);
  boolean deleteUserById(long id);

}
Enter fullscreen mode Exit fullscreen mode

Below we are defining a class called 'UserRepositoryImpl' which implements our interface. I haven't added all the code for the class, as we don't need to see that to understand the dependency inversion principle. So far we have an interface to define our operations and a concrete class for our user repository.

public class UserRepositoryImpl implements UserRepository {
  // Implement methods
}
Enter fullscreen mode Exit fullscreen mode

Now we create a class that interacts with our repository. This class takes our user repository as a parameter in its constructor. As you can see it is using polymorphism to depend on the interface rather than the concrete class. This allows us to replace the implementation (or concrete class) without having to modify the dependency of our UserController class.

public class UserController {

  private UserRepository repository;

  public UserController(UserRepository repository){
    this.repository = repository;
  }

  // More processing and operations

}
Enter fullscreen mode Exit fullscreen mode

This is the basis of the dependency inversion principle. Our class is dependent on an interface rather than a concrete class. However, it is important to note that you do not need to, and shouldn't, use this technique on every class in your codebase. Sometimes it doesn't make sense to use dependency inversion. If our implementation is not ever going to change then using the dependency inversion principle is pointless, as we will never have to switch out the implementation. If we are likely to change the implementation, such as changing the database implementation from SQL to in-memory, then it makes sense to use a dependency inversion approach.

This post was originally published on https://acroynon.com

Top comments (0)