DEV Community

Cover image for Injeção de Dependência
Danilo Barreto
Danilo Barreto

Posted on

Injeção de Dependência

O que é injeção de dependência? O que ela tem a ver comigo? O que ela come?

A injeção de dependência é uma prática essencial nos dias de hoje. Apesar de eu falar sobre ela no âmbito do Android, ela é utilizada em todas as linguagens orientadas a objeto, pois ela fornece um fraco acoplamento entre as entidades, permitindo que a sua aplicação possua uma boa arquitetura. Ela também possui um papel fundamental nos testes automatizados, pois permite quer façamos a troca das dependências sem realizar nenhuma modificação nas classes.

Vamos de exemplo

Imagine um carro. O carro possui uma dependência de um motor. Nós podemos representar dessa forma no Kotlin:

class Car {

    private val engine = Engine()

    fun start() {
        engine.start()
    }
}
Enter fullscreen mode Exit fullscreen mode

Nesse caso o motor está definido dentro do carro. Temos um acoplamento forte, pois o carro só permite um tipo de motor. Essa relação cria uma dificuldade caso eu queira um motor diferente. Nos testes automatizados, caso eu queira criar um FakeMotor() isso também não seria possível.
Mas com uma alteração já podemos ver algo diferente:

class Car(private val engine: Engine) {
   fun start() {
      engine.start()
   }
}
Enter fullscreen mode Exit fullscreen mode

Aqui já podemos dizer que temos uma injeção de dependência! Quando recebemos o Engine como parâmetro permitimos diferentes implementações como um EletricMotor ou um FakeMotor no caso de um teste automático. A forma demostrada acima é chamada de Injeção de Construtor. No Android podemos fazer de outra forma com Kotlin:

class car {

   lateinit var engine: Engine

   fun start() {
      engine.start()
   }
}

fun main(args: Array) {
   val car = Car()
   car.engine = Engine()
   car.start()
}
Enter fullscreen mode Exit fullscreen mode

Essa segunda forma é chamada se Injeção de Setter. Como Algumas classes são instanciadas por sistema, como Activities ou Fragments, as vezes não é possível se utilizar da Injeção por Construtor.

Essa é a forma manual de injeção de dependência. Agora imagine que você precisa instanciar todas a partes de um carro? Muita coisa né? Pra isso existem bibliotecas como o Dagger ou o Hilt que podem ajudar a fazer isso de forma automática criando um Graph em memória. Mas isso é assunto para um próximo artigo. A lição valiosa importante aqui é gerar um acoplamento forte da sua classe, pois isso engessa o seu modelo e torna qualquer teste e qualquer refatoração um trabalhão no futuro!

Top comments (0)