Artigo original: A quick intro to Dependency Injection: what it is, and when to use it

Introdução

Em engenharia de software, a injeção de dependências é uma técnica onde um objeto (ou método estático) fornece as dependências de outro objeto. Uma dependência é um objeto que pode ser usado (um serviço).

Acima temos a definição de injeção de dependências da Wikipédia. Ainda assim, não é algo fácil de entender. Vamos tentar entendê-la melhor.

Antes de entender o que ela significa em programação, vamos tentar entendê-la de um modo geral para compreender melhor o conceito específico.

Dependência ou dependente têm a ver com precisar de algo em termos de apoio. Se eu disser, por exemplo, que estamos dependendo demais de telefones celulares, significa que precisamos deles para fazermos outras coisas.

Assim, antes de entrar em injeção de dependências, primeiro vamos entender o que significa a dependência em programação.

Quando a classe A usa alguma funcionalidade da classe B, diz-se que a classe A tem uma dependência da classe B.

Em Java, antes de poder usar métodos de outras classes, primeiro precisamos criar o objeto daquela classe (ou seja, a classe A precisa criar uma instância da classe B).

Desse modo, transferir a tarefa de criação do objeto a outra entidade e usar diretamente a dependência é chamado de injeção de dependência.

1_TF-VdAgPfcD497kAW77Ukg
Se o código pudesse falar

Por que eu devo usar injeção de dependências?

Vamos supor que temos uma classe carro, que contém vários objetos, como rodas, motor etc.

Aqui, a classe carro é responsável por criar todos os objetos de dependência. Porém, o que faremos se decidirmos trocar as rodas da MRFWheels pelas rodas da Yokohama no futuro?

Precisaremos recriar o objeto carro com uma nova dependência da Yokohama. No entanto, ao usar a injeção de dependências (DI, de 'dependency injection' em inglês), podemos mudar as Rodas em tempo de execução (pois as dependências podem ser injetadas em tempo de execução em vez de em tempo de compilação).

Pense na DI como o intermediário do nosso código, que faz todo o trabalho de criar os objetos Rodas preferidos e de fornecê-los à classe Carro.

Isso torna nossa classe Carro independente da criação dos objetos Rodas, Bateria etc.

Basicamente, existem três tipos de injeção de dependências:

  1. injeção do construtor: as dependências são fornecidas por meio de um construtor da classe.
  2. injeção pelo setter: o cliente expõe o método setter que o injetor usa para injetar a dependência.
  3. injeção de interface: a dependência fornece um método injetor, que injetará uma dependência em qualquer cliente que for passado a ele. Os clientes devem implementar uma interface que expõe um método setter que aceita a dependência.

Desse modo, agora é responsabilidade da injeção de dependência:

  1. Criar os objetos
  2. Saber quais classes necessitam desses objetos
  3. Fornecer todos esses objetos

Se há alguma mudança nos objetos, a DI investiga isso e isso não deve preocupar a classe que usa esses objetos. Dessa forma, se os objetos mudarem no futuro, é a responsabilidade da DI fornecer os objetos apropriados à classe.

Inversão de controle — o conceito por trás da DI

O conceito por trás da DI é o de que uma classe não deve configurar suas dependências de modo estático. Elas devem ser configuradas por outra classe de fora dela.

Este é o quinto princípio do S.O.L.I.D — os cinco princípios básicos do design e da programação orientada a objetos, concebidos por Uncle Bob. Esse princípio declara que uma classe deve depender de uma abstração, não de elementos concretos (em termos simples, declarações explícitas no código).

De acordo com os princípios, uma classe deve concentrar-se em atender às suas responsabilidades e não em criar objetos de que precise para atender a essas responsabilidades. É aí que entra a injeção de dependências: ela fornece à classe os objetos necessários.

Observação: se quiser aprender sobre os princípios do SOLID, de Uncle Bob, visite este link (em inglês).

Benefícios do uso da DI

  1. Ajuda no teste unitário.
  2. O código de boilerplate é reduzido, já que a inicialização das dependências é feita pelo componente injetor.
  3. Ampliar a aplicação fica mais fácil.
  4. Ajuda a permitir o acoplamento fraco ('loose coupling', em inglês), que é importante na programação de aplicações.

Desvantagens da DI

  1. É um pouco complexa de aprender. Seu uso em excesso pode levar a problemas de gerenciamento e outros.
  2. Muitos erros em tempo de compilação acabam no tempo de execução.
  3. Os frameworks de injeção de dependências são implementados por reflexão ou programação dinâmica. Isso pode complicar o uso de automação pela IDE, como 'encontrar referências', 'mostrar a hierarquia de chamada' e a refatoração segura.

Você pode implementar a injeção de dependências por conta própria (diretamente) ou usar bibliotecas ou frameworks de terceiros.

Bibliotecas e frameworks que implementam a DI

Para saber mais sobre a injeção de dependências, você pode verificar os recursos abaixo (em inglês):

Java Dependency Injection — DI Design Pattern Example Tutorial — JournalDev

Using dependency injection in Java — Introduction — Tutorial — Vogella

Inversion of Control Containers and the Dependency Injection pattern — Martin Fowler

Espero que isso seja útil!

Se gostou do artigo e deseja ler mais artigos incríveis, siga o autor no Medium (Bhavya Karia) e mostre seu apoio, pois isso o motiva a escrever mais.

Se tiver perguntas ou comentários, conecte-se ao autor pelo LinkedIn, pelo Twitter ou pelo Facebook.

Primeira edição:

Agradeço a Sergey Ufocoder por ter traduzido este artigo para o russo. Peço aos meus amigos russos e a quem entende o idioma que leiam o artigo.

Link para o artigo em russo

Além disso, se quiser aplicar a DI em JavaScript e se estiver procurando por uma biblioteca para isso, Jo Surikat (texto em inglês) sugere experimentar a biblioteca Di-Ninja.

Mais uma biblioteca de DI em JavaScript incrível foi sugerida por Nicolas Froidure (texto em inglês), a knifecycle.

Segunda edição:

Se você é um desenvolvedor em PHP, não se preocupe. Temos DI para você também. Gordon Forsythe (texto em inglês) recomendou esta biblioteca fantástica, que você pode querer experimentar, a auryn.

O autor agradece a todos pelos comentários positivos que vem recebendo. Compartilhe o artigo para que mais pessoas possam tirar proveito dele.

Se aprendeu alguma coisa de valor nessa leitura, compartilhe o artigo com outras pessoas!