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?
Respostas:
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.
fonte
N
horas ... 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!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
:DependencyLookupConstructor
é acoplado a um particularDependencyClass
neste caso. Mas, ambos estão acopladosDependencyClass
. O verdadeiro mal, se houver um aqui, não é necessariamente o acoplamento, é queDependencyLookupConstructor
precisa mudar se deDependencyClass
repente precisar de suas próprias dependências injetadas 1 .No entanto, esse construtor / classe é ainda mais frouxamente acoplado:
Se você estiver trabalhando em C #, o acima permitirá que você
ServiceLocator
retorne qualquer coisa quandoGetMyDoer()
for chamada, desde que possua odo()
que aDependencyLocatingConstructor
possuido()
. 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:
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
User
ouIUser
para diferentes propósitos: por exemplo,Locator.GetAdministrator()
versusLocator.GetAuthor()
- ou o que for. Meu código pode solicitar o que ele precisa funcionalmente, mesmo sem saber quais interfaces ele suporta.fonte
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 emIDependency
. 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.DependencyClass
seja 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" :)dynamic
parâmetros. (Mas nãovar
parâ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.dynamic
orvar
e obtendo um objeto de um localizador, você ignora a interface e usa qualquer classe que possa odo()
que você precisa, independentemente de essa classe implementar algumaIDoer
interface. 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çado()
.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 .
fonte
instance creation
mas 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
Eu iria com o encapsulamento de dependência . Isso expressa que a dependência está bloqueada em vez de visitar e sair novamente.
fonte