SOLID - The Letter D - Dependency Inversion Principle
Tags: solid, architecture, dependencyinversion, principle
Published: 2021-04-19 18:07:16

The last SOLID principle is the Dependency Inversion Principle (DIP). This principle tell us that the most flexible systems use abstract dependencies instead of concrete ones. The way you achieve this is using interfaces.

# What is interface?
Talking about software development, interface is a abstract type that contains no data but defines behaviours as method signatures.
For example, imagine we want to insert an account in our database:

``` typescript
interface AddAccountRepository {
  add: (email: String, password: String) => Account
}
```
You can see that the interface AddAccountRepository doesn't have an implementation, there is only a signature of the Add method. But you must be wondering: how could I use this method if there is no code?

# How to implement an interface?
Imagine we would like to write the code of Add method. We have to create a new class to implement this interface.

``` typescript
class AccountMongoRepository implements AddAccountRepository {
}
```

If we write only this lines of code our IDE (Visual Studio, Eclipse, etc) will say that we must create a method called "Add". It means that when we use the word "implements" and after an interface, we have to describe and implement all the signatures of this interface. So, our code would  look like this:

``` typescript
class AccountMongoRepository implements AddAccountRepository {
  add (email: String, password: String): Account {
  // insert an user into a MongoDb
  }
}
```
If we had another interface called DeleteAccountRepository.
``` typescript
interface DeleteAccountRepository {
  delete: (email: String) => void
}
```
We just have to add the interface on the "implements" part and write the delete method implementation.
``` typescript
class AccountMongoRepository implements AddAccountRepository, DeleteAccountRepository {
  add (email: String, password: String): Account {
  // insert an user into a MongoDb
  }

  delete (email: String): void {
  // delete an user
  }
}
```

Now we have an interface and a class that implements the methods of these interfaces. Now, how can we use this interface?

# How to use an the implementation of an interface?
We have to inject this dependency in our class to use their implementations methods. If you want to know more about dependency injection, [click here](https://dev.to/vitoraa/why-you-should-use-dependency-injection-31h9).

``` typescript
class DbAddAccount {
  constructor (private readonly addAccountRepository: AddAccountRepository) { }

addUser (email: String, password: String): Account {
    accountCreated = this.addAccountRepository.add(name, password)
    return accountCreated
  }
}
```
In the code above we see the injection of the interface AddAccountRepository. The class DbAddAccount doesn't know about the implementation about the method Add. This is important because we don't have to be aware of changes in dependencies classes.

# Why is the name Dependency Inversion?
In one cenario, if we use a concrete class to insert a user into a database, the DbAddAccount class would be dependent of this class.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yqode0q3nlf3nk0whg70.PNG)

If we have to change our database to Postgres, for example, our class would be affected. Using the injection dependency we invert the dependency as we see in the image below.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ehak8arnx19xrw28h7c3.PNG)

Now DbAddAccount use AccountMongoRepository through the interface AddAccountRepository. The DbAddAccount doesn't depend on AccountMongoRepository, but on the contrary. To be used, the AccountMongoRepository depedens on DbAddAccount.

# Conclusion
Dependency Inversion Principle and Dependency Injection work together. We have to use one to get the other. Although can be more difficult to understand and to code, if you use both in your code the reusability will increase, your code will be more clean and more easier for changes.