Termo técnico para denotar o oposto da injeção de dependência?

12

Isso é mais uma nomenclatura (redação técnica) do que uma questão puramente técnica. Estou tentando escrever uma proposta de refatoração (e atribuí-la a mim mesma) centrada na expansão da injeção de dependência em nosso aplicativo. Embora utilizemos o Spring para autowiring beans, ainda existem instâncias que instanciam o uso de beans MyClass obj = new MyClass(...), que podem ser totalmente injetados. Gostaria de fazer minha proposta usar nomenclatura elegante e me referir ao padrão de design oposto ao DI com um termo adequado.

"Acoplamento rígido" é um termo adequado que se destaca como antônimo de DI?

anfíbio
fonte
1
Sim, o acoplamento descreve o ato de usar nomes explícitos de classe em outras classes e o estado resultante de uma base de código.
precisa saber é o seguinte
11
Não, o acoplamento rígido descreve apenas a propriedade do código resultante, não o oposto de DI. Você pode usar o DI e ainda ter um acoplamento apertado por razões completamente diferentes.
Doc Brown
1
Concordou que DI e acoplamento apertado não são opostos .
Eric King
@EricKing mostra. +1 por sinal.
Candied_orange 30/09/16
1
"Sucção por dependência" .
SeldomNeedy

Respostas:

30

Não. O acoplamento apertado é muito mais do que o que a injeção de dependência trata.

A injeção de dependência externaliza uma decisão de implementação. Isso ajuda bastante a desacoplar, mas o acoplamento é mais do que isso.

Um bom antônimo para injeção de dependência é codificar uma dependência . Ao construir (usar novo ou usar diretamente alguma fábrica) dentro de um objeto de comportamento, você fundiu duas preocupações diferentes. Um localizador de serviço ajuda a desacoplar, mas deixa você acoplado ao próprio localizador de serviço.

O acoplamento é mais do que apenas separar construção e comportamento. Se eu tenho 101 métodos que precisam ser chamados em alguma ordem específica da classe A à classe B, estou fortemente associado. Não importa o quão maravilhosamente separados sejam construção e comportamento.

O acoplamento é uma medida da interdependência dos dois objetos. Qualquer coisa que contribua para tornar difícil fazer alterações em uma sem afetar a outra está contribuindo para o acoplamento. A injeção de dependência ajuda nisso, mas não é tudo isso.

candied_orange
fonte
Sim, codificação embutida (uma dependência), em vez de injetá-la (em tempo de execução), é exatamente o que eu sugeriria, também, você era um pouco mais rápido que eu.
Doc Brown
7
@DocBrown Às vezes eu gostaria que este lugar não colocasse tanta ênfase em ser rápido. Eu gostaria de ouvir como você colocaria.
Candied_orange 30/09/16
Boa resposta - a injeção de dependência não implica dissociação. Acreditar de outra maneira leva a um caminho ruim
Ant P
1
@CandiedOrange Talvez alguém deva sugerir na meta que as respostas permaneçam ocultas por um período de tempo. E / ou que os votos sejam ocultos da exibição pública por Nhoras ... Ou até que uma resposta seja selecionada. Eu sei que não sou totalmente objetivo quando uma resposta já tem 10 votos e as outras 5 respostas não têm nenhuma!
Svidgen
1
@svidgen pesquisa "arma mais rápida do oeste" na meta. A questão já tem uma longa história.
Candied_orange 30/09/16
6

A rigor, a Injeção de Dependência realmente não se opõe à Injeção de Dependência - e, portanto, a qualquer estratégia de gerenciamento de dependência que não seja a Injeção de Dependência.

O acoplamento [indesejado], embora não seja exatamente um problema ortogonal, pode ocorrer ou ser mitigado de qualquer maneira. Ambos são acoplados a DependencyClass:

public DependencyInjectedConstructor(DependencyClass dep) {
  dep.do();
}

public DependencyLookupConstructor() {
  var dep = new DependencyClass();
  dep.do();
}

DependencyLookupConstructoré acoplado a um particular DependencyClassneste caso. Mas, ambos estão acoplados DependencyClass. O verdadeiro mal, se houver um aqui, não é necessariamente o acoplamento, é que DependencyLookupConstructorprecisa mudar se de DependencyClassrepente precisar de suas próprias dependências injetadas 1 .

No entanto, esse construtor / classe é ainda mais frouxamente acoplado:

public DependencyLocatingConstructor() {
  var dep = ServiceLocator.GetMyDoer();
  dep.do();
}

Se você estiver trabalhando em C #, o acima permitirá que você ServiceLocatorretorne qualquer coisa quando GetMyDoer()for chamada, desde que possua o do()que a DependencyLocatingConstructorpossui do(). Você obtém o benefício da validação de assinatura em tempo de compilação sem precisar ser acoplado a uma interface completa 2 .

Então, escolha seu veneno.

Mas, basicamente, se houver um "oposto" concreto da injeção de dependência, seria outra coisa no campo das "Estratégias de gerenciamento de dependência". Entre outros, se você usasse um dos seguintes itens na conversa, eu o reconheceria como sendo NÃO injeção de dependência:

  • Padrão do Localizador de Serviço
  • Localizador / Local de Dependência
  • Construção direta de objeto / dependência
  • Dependência oculta
  • "Injeção sem dependência"

1. Ironicamente, alguns dos problemas que o DI resolve em níveis mais altos são como resultado do uso excessivo do DI nos níveis mais baixos. Tive o prazer de trabalhar em bases de código com complexidade desnecessária em todo o mundo, como resultado de acomodar vários lugares onde essa complexidade realmente ajudou ... Sou admitidamente influenciado por más exposições.

2. O uso da localização do serviço também permite que você especifique facilmente diferentes dependências do mesmo tipo por sua função funcional a partir do código de chamada , embora ainda seja bastante independente sobre como a dependência é construída. Suponha que você precise resolver Userou IUserpara diferentes propósitos: por exemplo, Locator.GetAdministrator()versus Locator.GetAuthor()- ou o que for. Meu código pode solicitar o que ele precisa funcionalmente, mesmo sem saber quais interfaces ele suporta.

svidgen
fonte
2
A salvação DependencyInjectedConstructor(DependencyClass dep)é que DependencyClass pode ser uma interface ou classe abstrata. É por isso que me entristece que os codificadores C # usem um prefixo de interface, como em IDependency. Como cliente, realmente não é da minha conta o que é essa coisa de Dependência. Desde que eu não o construa, tudo o que preciso saber é como conversar com ele. O que é é problema de outra pessoa.
Candied_orange 30/09/16
Os pontos são que o DI ainda o acopla a essa interface e não exige que DependencyClassseja uma interface abstrata. É única requer que a lógica de construção / configuration / local existente "em outro lugar." ... Bem, e mais pertinente para a questão, a questão é que DI não é "o oposto do acoplamento forte" :)
svidgen
Na verdade ... Eu posso estar um pouco fora dos limites ao dizer que o DI necessariamente o acopla a uma interface, mesmo em C #. Embora eu os tenha evitado em C #, tenho a impressão de que também posso aceitar dynamicparâmetros. (Mas não varparâmetros, se a memória servir.) Portanto, com o DI em C #, acho que preciso codificar contra uma interface ou renunciar totalmente à validação em tempo de compilação.
Svidgen
Os objetos são acoplados às interfaces. Se você usa ou não a palavra-chave da interface. Isso é o que é uma interface adequada. Tudo o que você precisa estar acoplado. O que você evoca são detalhes de implementação e coisas extras que você não precisa. Podemos formalizar isso usando a palavra-chave interface para permitir que o cliente diga ao mundo: "Tudo o que preciso é isso". Mas não precisamos. Heck, podemos fazer digitação de pato, bem em alguns idiomas.
Candied_orange 30/09/16
Não tenho certeza se estamos em total desacordo. Mas, para esclarecer ... Objetos são acoplados internamente a suas próprias interfaces, sim. Mas, a própria interface só impõe o acoplamento de dependência se a interface for nomeada explicitamente. Em C #, usando dynamicor vare obtendo um objeto de um localizador, você ignora a interface e usa qualquer classe que possa o do()que você precisa, independentemente de essa classe implementar alguma IDoerinterface. Em outras palavras, se temos A-> B <-C, DI desacopla A de C, mas requer que A e C sejam acoplados a B e impede o uso de D, mesmo que D o faça do().
Svidgen
2

Eu não sei que há específica, terminologia da indústria amplamente aceito, mas as alternativas que vêm à mente incluem a criação interna exemplo , a criação de dependência interna , dependências locais ou dependências escopo localmente .

mcknz
fonte
2
eu gosto, instance creationmas não é específico o suficiente. O DI cria instâncias, mas por meio do controlador e não no nível do aplicativo. talvezinternal instance creation
anfphient
1

Eu iria com o encapsulamento de dependência . Isso expressa que a dependência está bloqueada em vez de visitar e sair novamente.

Martin Maat
fonte