Como a injeção de dependência aumenta o acoplamento?

32

Na página da Wikipedia sobre injeção de dependência, a seção de desvantagens nos diz o seguinte:

A injeção de dependência aumenta o acoplamento exigindo que o usuário de um subsistema forneça as necessidades desse subsistema.

com um link para um artigo contra injeção de dependência .

A injeção de dependência faz uma classe usar a interface em vez da implementação concreta. Isso deve resultar em menor acoplamento , não?

o que estou perdendo? Como a injeção de dependência está aumentando o acoplamento entre as classes?

BЈовић
fonte
2
Não tenho certeza de quem escreveu essa lista de desvantagens, mas eu aceitaria com um grão de sal. Por exemplo, eu vi o DI reduzir o tamanho de uma base de código em 2/3, eliminando uma tonelada de código de configuração redundante.
Rob
@RobY Eu usei o factory principalmente para injetar a dependência, e minha experiência é que aumenta o tamanho do código, mas simplifica o teste.
BЈовић
Tente usar uma alternativa como Registro ou Passagem de Contexto;) Ou então, um código que instancia objetos e extrai suas propriedades da configuração. Estou falando principalmente da diferença entre agora e 15 anos atrás.
Rob
Relacionado: stackoverflow.com/a/9503612/264697 . A resposta de Mark Seemann explica como o acoplamento geral é reduzido usando a Injeção de Dependência.
Steven

Respostas:

42

Então, o que estou perdendo?

A injeção de dependência diminui o acoplamento entre uma classe e sua dependência. Mas aumenta o acoplamento entre uma classe e seu consumidor (já que o consumidor precisa de mais informações para criá-la) e a dependência e seu consumidor (já que o consumidor precisa saber a dependência a ser usada).

Muitas vezes, essa é uma boa troca. A classe não deve conhecer os detalhes sobre suas dependências além de uma interface e deve ser responsabilidade do aplicativo unir bits específicos de código.

Telastyn
fonte
Certo, o acoplamento diminui de uma maneira e aumenta de outra.
Paul Draper
Mas o consumidor não a cria; esse é o ponto.
Casey
@emodendroket - Eh? A inversão do controle permite que o consumidor não o crie. A injeção de dependência é ortogonal a isso.
Telastyn
Bem, você está fazendo uma distinção com a qual não estou familiarizado, já que geralmente os termos são usados ​​de forma intercambiável.
Casey
22

Suponha que você tenha um subsistema Sque depende de uma conexão com o banco de dados D. Sem injeção de dependência, há um acoplamento relativamente apertado entre Se D, porque Sprecisa saber como usarD e como criá-lo. O restante do sistema, no entanto, pode ignorar alegremente essa dependência entre Se D.

Com a injeção de dependência, o acoplamento entre Se Dse torna mais solto, porque você remove do Sconhecimento como criar um D. Ssó precisa saber como usá-lo. O aumento do acoplamento geral vem do fato de que outras partes do sistema agora precisam conhecer De possivelmente como criar um. A extensão desse aumento no acoplamento depende de como a dependência Dé injetada noS :

  • Com injeção de construtor, o criador deS precisa de uma dependência De, possivelmente, do conhecimento de como criar uma.
  • Com a injeção no nível do método , cada chamador de um método Spelo qual um Dé injetado precisa de uma dependência deD e, possivelmente, do conhecimento de como criar um.

Em qualquer um dos casos, o número de classes que depende de Daumentos e o conhecimento de como criar uma Dainda precisam estar presentes em algum lugar do sistema. Isso cria um aumento geral do acoplamento.

Bart van Ingen Schenau
fonte
Ok, faz sentido para injeção de construtor e setter. Mas se alguém usa padrão de fábrica ou estratégia, a criação é movida para lá e a classe usa apenas o objeto injetado. Ou isso não é uma injeção de dependência (apenas inversão de controle)?
BЈовић
Mesmo com a injeção de fábrica, o criador Sprecisa fornecer uma fábrica D, o que significa que precisa saber que Susa D(ou pelo menos alguma interface dela).
Idan Arye
7

Eu discordo totalmente que aumenta o acoplamento.

Sem injeção de dependência, você tem um acoplamento rígido entre um subsistema e a implementação concreta da dependência.

Com a injeção de dependência, você separou o subsistema da implementação da dependência.

Argumentar que ele aumenta o acoplamento entre o consumidor e esse subsistema é MUITO questionável, pois implica que o consumidor agora está fortemente acoplado à dependência exigida pelo subsistema. Tudo o que isso significa é que você está escrevendo um código fortemente acoplado que une seu consumidor à dependência. Idealmente, TODO o seu código é dissociado.

Injeção de Construtor:

A resolução de dependência é manipulada por um contêiner de injeção de dependência ou uma fábrica. O consumidor pode obter uma implementação concreta do subsistema do contêiner de injeção de dependência ou de uma fábrica.

O consumidor não precisa saber como é o construtor do subsistema. Não há acoplamento à dependência do subsistema.

Injeção de método:

O mesmo que a injeção do construtor, exceto que agora o consumidor precisa obter uma instância concreta da dependência do contêiner ou da fábrica (ou mesmo que o método / construtor seja injetado) e injetá-lo no método. Novamente, o consumidor não está acoplado a uma implementação concreta da dependência.

TL; DR O pior caso para injeção de dependência em um subsistema é que o acoplamento é alterado para o código do consumidor. NÃO EXISTE AUMENTO GERAL NO ACOPLAMENTO.

O melhor caso é que agora todos os sistemas estão fracamente acoplados e a injeção de dependência é controlada através de contêineres ou fábricas de injeção de dependência.

Falcão
fonte