DEV Community

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

Posted on Edited 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
 
thiagodevvv profile image
Thiago Henrique da S. Ferrari

boa!!!!!

Collapse
 
gabrielasil profile image
Gabriela Silva

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