Personalize as preferências de consentimento
Utilizamos cookies para ajudá-lo a navegar com eficiência e executar determinadas funções. Você encontrará informações detalhadas sobre todos os cookies em cada categoria de consentimento abaixo.

Os cookies categorizados como “Necessários” são armazenados no seu navegador, pois são essenciais para ativar as funcionalidades básicas do site.

Também utilizamos cookies de terceiros que nos ajudam a analisar como você usa este site, armazenam suas preferências e fornecem conteúdo e anúncios que são relevantes para você. Estes cookies só serão armazenados no seu navegador com o seu consentimento prévio.

Você pode optar por ativar ou desativar alguns ou todos esses cookies, mas a desativação de alguns deles pode afetar sua experiência de navegação.
Sempre ativo

Necessary cookies are required to enable the basic features of this site, such as providing secure log-in or adjusting your consent preferences. These cookies do not store any personally identifiable data.

Não há cookies para exibir.

Functional cookies help perform certain functionalities like sharing the content of the website on social media platforms, collecting feedback, and other third-party features.

Não há cookies para exibir.

Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics such as the number of visitors, bounce rate, traffic source, etc.

Não há cookies para exibir.

Performance cookies are used to understand and analyse the key performance indexes of the website which helps in delivering a better user experience for the visitors.

Não há cookies para exibir.

Advertisement cookies are used to provide visitors with customised advertisements based on the pages you visited previously and to analyse the effectiveness of the ad campaigns.

Não há cookies para exibir.

Conceitos de Programação

O que é Injeção e Inversão de dependências?

31 de outubro de 2022

No mundo da programação, existe uma relação entre os termos injeção e inversão de dependências. Porém, geralmente são mal utilizados no decorrer de um projeto ou pouco conhecidos no desenvolvimento de sistemas digitais.

Neste artigo, iremos apresentar uma breve introdução do que é cada um desses termos e de como utilizá-los corretamente. Mas, para entendê-los, primeiramente devemos compreender o significado de dependências.

O que são dependências?

Quando estamos programando, podemos criar classes para as mais diversas finalidades e funcionalidades. Então, se você instancia um objeto dentro de outra classe, isso automaticamente a torna uma dependência dessa classe. É nítido que não fazemos esse tipo de coisa apenas uma vez durante o projeto. Isso é feito em diversos momentos. Por isso, gera código com forte acoplamento ou baixa coesão segundo os princípios do SOLID.

Codar dessa maneira é um processo quase que natural utilizado pela maioria dos desenvolvedores que ainda estão aprendendo ou desconhecem alguns princípios e consequências que um código fortemente acoplado pode gerar no futuro.

Veja que, no exemplo abaixo, queremos conectar o CreateUserController, para que ele possa criar um User a partir de um repositório CreateUserRepository ao realizar alguma solitação HTTP do tipo POST a determinada rota.

Injeção e Inversão de Dependências 1

Perceba que, utilizando essa abordagem, uma classe começa a depender de uma outra para que a primeira funcione. E isso deve ser evitado desacoplando o uso de um objeto da sua criação, deixando as classes independentes.

Qual o problema gerado por essa abordagem?

Sempre que criamos uma instância de CreateUserController, uma outra instância (com a implementação direta da criação do usuário no banco) de CreateUserRepository deve estar disponível para que haja compilação do nosso código.

Dito isso, podemos pensar que o sentido das dependências segue de tal forma:

  • CreateUserController depende diretamente de CreateUserRepository

Injeção e Inversão de Dependências 2

Injeção de dependência

Podemos dizer que injeção de dependência é basicamente passar via construtor as dependências (já instanciadas fora da classe) que seu componente irá utilizar. Chamamos esse tipo de injeção de Constructor Injection.

Perceba abaixo que melhoramos o nosso código injetando uma instância de CreateUserRepository no construtor de CreateUserController, ao invés de instanciarmos esse repositório diretamente de dentro do nosso controller.

Injeção e Inversão de Dependências 3

Mas isso ainda não é o suficiente!

O CreateUserController ainda depende de CreateUserRepository.

Injeção e Inversão de Dependências 4

Antes de mostrar a solução derradeira para essa situação e ainda falando um pouco sobre a desvantagem que é utilizar esse tipo de abordagem, não poderíamos, por exemplo, ‘mockar’ valores a partir de testes unitários utilizando a classe CreateUserRepository (que faz uma implementação e operações diretamente com um banco de dados SQL) para um banco de dados simulado em memória com o intuito de criar ou utilizar testes unitários. Isso porque nossos testes deixariam de ser unitários, uma vez que estamos dependendo de uma implementação que utiliza a persistência nos dados.

Ou seja, já que amarramos nosso CreateUserController, ele então depende exclusivamente da implementação contida em CreateUserRepository.

Dito isso, o que buscamos de fato? Precisamos inverter as direções! Ao invés de dependermos de implementações, devemos depender de contratos ou interfaces.

Inversão de dependência

O Dependency Inversion Principle é um princípio do SOLID que afirma: dependa de abstrações e não de implementações.

Segundo Uncle Bob, esse princípio pode ser definido assim:

  1. Módulos de alto nível não devem depender de módulos de baixo nível. Ambos devem depender da
    abstração.
  2. Abstrações não devem depender de detalhes. Detalhes devem depender de abstrações.

Então, a inversão de dependência é uma prática que nos permite desacoplar componentes. Agora, veja como se comporta a direção e o fluxo de dependências:

Injeção e Inversão de Dependências 5

 

Neste ponto, nosso CreateUserController aponta para uma interface que abstraímos a criação de um usuário, ao invés da classe concreta CreateUserRepository. Isto é, inserindo uma interface ICreateUserRepository entre os dois componentes: CreateUserController eCreateUserRepository. Dessa forma, iremos ver a seguir como isso se reflete no código:

Injeção e Inversão de Dependências 6

Assim, no CreateUserController, iremos consultar a interface ICreateUserRepository ao invés da classe CreateUserRepository.

Injeção e Inversão de Dependências 7

Dessa forma, acabamos de inverter as dependências.

Qual a real vantagem da Injeção e Inversão de dependências?

Anteriormente, falamos que não seria possível criar nossos testes unitários ‘mockados’ passando um CreateUserRepository em um CreateUserController. Isso porque os testes ficariam lentos e precisaríamos de uma conexão com o banco de dados para executar esse test.

Entretanto, utilizando inversão de dependências podemos escrever uma classe qualquer MockCreateUserRepository, que implementa a interface ICreateUserRepository, e cria em memória um atributo que seja um array de Users para simularmos um banco de dados. Com isso, será possível executarmos testes mais rápidos e de forma íntegra, de acordo com nosso negócio.

Injeção e Inversão de Dependências 8

Conclusão

Passando uma instância dessa classe MockCreateUserRepository para o nosso CreateUserController, você pode escrever um teste unitário utilizando jest sem preocupações com operações reais em um banco de dados.

Lido até aqui, agora você pode ter uma ideia primária de como colocar em prática os princípios da inversão e injeção de dependências em suas classes, utilizando de interfaces como principal aliado. Se tiver em dúvida, lembre-se sempre: dependa de abstrações, e não de implementações.

Veja também:

Introdução ao React JS

Autor: Clidenor Issac de Almeida Cabral.

Imagem padrão

Autor

Julia Ilkiu

Artigos relacionados

Receba nossa
newsletter

Assine nossa newsletter e receba as últimas
novidades sobre o mundo da tecnologia.

    Eu autorizo a Luby a usar meus dados para o envio de conteúdos personalizados.