DEV Community

Cover image for Injeção de Dependência em JavaScript
Silvio Ferreira
Silvio Ferreira

Posted on • Updated on

Injeção de Dependência em JavaScript

Neste artigo, será abordado um pouco sobre injeção de dependência, uma técnica muito útil para deixar o sistema mais flexível, diminuindo o acoplamento de código, facilitando assim a manutenção e realização de testes unitários.

Contextualizando

Em um exemplo da vida real, vamos transcrever a situação para o código:

No restaurante da esquina, existe um garçom que serve um pedaço de pizza para os clientes, mas para conseguir servi-los da melhor forma, o garçom precisa de uma lâmina que consiga cortar um pedaço de pizza.

Nesse caso, podemos ter duas classes:

A classe Knife que representa uma faca, tem um método que retorna um pedaço de pizza.

class Knife {
    cutPizza() {
        return '🍕 cut by a Knife'
    }
}
Enter fullscreen mode Exit fullscreen mode

A classe Waiter que representa um garçom, possui um método que serve a pizza, atualmente instanciando uma faca dentro deste método e usando-a para cortar um pedaço e servir.

class Waiter {
    servePizza() {
        const knife = new Knife()
        const pizzaSlice = knife.cutPizza()
        return pizzaSlice
    }
}
Enter fullscreen mode Exit fullscreen mode

Instanciando as classes e executando o programa temos o seguinte resultado:

const waiter1 = new Waiter()
const pizzaSlice = waiter1.servePizza()

console.log(pizzaSlice) // 🍕 cut by a Knife
Enter fullscreen mode Exit fullscreen mode

Com o garçom usando uma faca, nosso sistema está funcionando perfeitamente! Mas... E se o chefe do restaurante decidir que agora as pizzas devem ser servidas com um cortador de pizza mais apropriado?

De primeira, pensamos em substituir a implementação da classe Waiter no método servePizza(), substituindo a instância de Knife por uma nova classe que saiba cortar pizza.

Funciona, porém sempre irá ter o trabalho de alterar o código interno da classe Waiter.

Isso indica que a classe Waiter estava acoplada a Knife e agora a esta nova classe que foi criada para substituí-la.

E se, depois de contratar dois novos garçons que também estão usando um cortador de pizza, o chefe compra uma machadinha personalizada com o logo da empresa, além disso pede para cada um dos 3 garçons usarem cortadores diferentes?

Resolvendo o problema

Agora já fica inviável alterar sempre o código interno da classe Waiter, enfim iremos utilizar a injeção de dependência para que os garçons consigam servir pizza com qualquer tipo de ferramenta que possa cortá-la.

Para isso, vamos fazer pequenos ajustes na implementação da classe Waiter:

class Waiter {
    constructor(blade) {
        this.blade = blade
    }

    servePizza() {
        const pizzaSlice = this.blade.cutPizza()
        return pizzaSlice
    }
}
Enter fullscreen mode Exit fullscreen mode

Adicionamos um construtor que espera receber qualquer objeto de lâmina que possua o método cutPizza(), já no método servePizza() não instanciamos mais de forma direta uma classe e sim usamos a instância recebida no construtor!

Agora, independentemente de qual for a ferramenta utilizada pelo garçom, desde que ela consiga cortar pizza, será possível servi-la:

const knife = new Knife()
const waiter1 = new Waiter(knife)
const pizzaSlice = waiter1.servePizza()

console.log(pizzaSlice) // 🍕 cut by a Knife
Enter fullscreen mode Exit fullscreen mode

Exemplificando os três garçons e suas ferramentas diferentes:

class PizzaCutter {
    cutPizza() {
        return  '🍕 cut by a Pizza Cutter'
    }
}

class PizzaAxe {
    cutPizza() {
        return  '🍕 cut by a Pizza Axe'
    }
}
Enter fullscreen mode Exit fullscreen mode

Definidas as classes das novas ferramentas de cortar pizza, podemos executar nosso código:

const knife = new Knife()
const pizzaCutter = new PizzaCutter()
const pizzaAxe = new PizzaAxe()

const waiter1 = new Waiter(knife)
const waiter2 = new Waiter(pizzaCutter)
const waiter3 = new Waiter(pizzaAxe)

const pizzaSlice1 = waiter1.servePizza()
const pizzaSlice2 = waiter2.servePizza()
const pizzaSlice3 = waiter3.servePizza()

console.log(pizzaSlice1) // 🍕 cut by a Knife
console.log(pizzaSlice2) // 🍕 cut by a Pizza Cutter
console.log(pizzaSlice3) // 🍕 cut by a Pizza Axe
Enter fullscreen mode Exit fullscreen mode

Agora você já está pronto para criar projetos mais desacoplados e deixar sua aplicação mais flexível!

Top comments (2)

Collapse
 
gabrielasil profile image
Gabriela Silva

Show demais. Bem escrito e fácil de entender!

Collapse
 
thiagodevvv profile image
Thiago Henrique da S. Ferrari

boa!!!!!