A injeção de dependência manual é uma alternativa melhor à composição e ao polimorfismo?


13

Primeiro, sou programador iniciante; Na verdade, estou terminando o curso AS com um projeto final no verão. No meu novo trabalho, quando não há um projeto para mim (eles estão esperando para preencher a equipe com mais contratações), recebi livros para ler e aprender enquanto espero - alguns livros didáticos, outros nem tanto (como o Code Complete). Depois de ler esses livros, voltei-me à Internet para aprender o máximo possível e comecei a aprender sobre o SOLID e o DI (falamos um pouco sobre o princípio de substituição de Liskov, mas não muitas outras idéias sobre o SOLID). Então, como aprendi, sentei-me para aprender melhor e comecei a escrever algum código para utilizar o DI manualmente (não há estruturas de DI nos computadores de desenvolvimento).

A coisa é que, ao fazê-lo, percebo que parece familiar ... e parece que é muito parecido com o trabalho que fiz no passado usando composição de classes abstratas usando polimorfismo. Estou perdendo uma imagem maior aqui? Existe algo sobre DI (pelo menos à mão) que vai além disso? Eu entendo a possibilidade de ter configurações que não estão no código de algumas estruturas de DI, com grandes benefícios no que diz respeito a mudar as coisas sem precisar recompilar, mas ao fazer isso manualmente, não tenho certeza se é diferente do indicado acima ... Algumas dicas sobre isso seriam muito úteis!

Respostas:


21

A idéia fundamental no DI é simplesmente inserir dependências em objetos, em vez de deixá-las extrair dependências de fora. Isso também foi chamado de "inversão de controle" anteriormente. Isso permite controlar dependências muito melhor e - por último mas não menos importante - escrever código que é fácil de testar na unidade.

As estruturas de DI apenas se baseiam nessa idéia e (parcialmente) automatizam a parte muitas vezes tediosa de conectar dependências de objetos. Caso contrário, isso pode exigir uma quantidade significativa de código em um projeto maior quando feito à mão.

Para definir dependências, além dos arquivos de configuração externos, também é possível usar anotações de código hoje em dia, por exemplo, em linguagens como Java e C #. Isso pode trazer o melhor dos dois mundos: conectar dependências em um estilo declarativo, mas dentro do próprio código, ao qual ele pertence logicamente. Para mim, a possibilidade de alterar dependências sem precisar recompilar não é tão valiosa, como raramente é feita na vida real (exceto em alguns casos especiais), mas introduz uma separação muitas vezes artificial de dependências das classes e objetos definidos no código. .

Para retornar à sua pergunta do título, o DI não é uma alternativa à composição nem ao polimorfismo; afinal, isso é possível por esses dois.


1
Injeção de Dependência (DI) é uma forma de Inversão de Controle (IoC).
Matthew Flynn

@MatthewFlynn, de fato. Para referência: martinfowler.com/articles/injection.html
Péter Török

1
Essa é a minha referência. Ele fala sobre os novos "contêineres leves" fazendo inversão de controle, algo que já era comum porque os ouvintes de eventos da interface do usuário eram uma forma de IoC. Ele define a ligação de objeto que Spring e outros contêineres IoC fazem como Injeção de Dependência para diferenciá-lo da outra forma de Inversão de Controle.
Matthew Flynn

Opa - eu perdi o "de fato". Eu pensei que você estava me contradizendo ... Desculpe.
Matthew Flynn

Seu último parágrafo me faz sentir um pouco melhor; o tempo todo em que trabalhei no meu pequeno projeto de aprendizado, fiquei dizendo a mim mesmo: "isso parece polimorfismo ...". Infelizmente, o .net e o c # no meu trabalho estão terrivelmente desatualizados, mas, ao investigá-lo, o Unity é a estrutura de c # integrada de que você está falando?
Drake Clarris

22

O melhor artigo que eu já li sobre o assunto foi o de James Shore . Eu venho fazendo " DI à mão " há séculos, como parte da abstração e polimorfismo. Então, depois que entrei no mundo profissional e continuei ouvindo esse termo, tive uma grande desconexão entre o que achava que a palavra deveria significar e o que realmente significa:

"Injeção de dependência" é um termo de 25 dólares para um conceito de 5 centavos.

Isso é do post de Shore, que esclareceu tudo para mim. Por exemplo:

Dado

class Engine {public abstract void start()}
class V8 extends Engine {...}
class V6 extends Engine {...}

Em vez de escrever:

class Car
{
    private Engine engine;
    public Car()
    {
        this.engine = new V6();
    }

    public void start()
    {
        this.engine.start();
    }
}

Você escreve algo assim:

class Car
{
    private Engine engine;
    public Car(Engine a)
    {
        this.engine = a;
    }

    public void start()
    {
        this.engine.start();
    }
}

...

Car F = new Car(new V8());

E isso evita que a Carinstância precise lidar com Enginedetalhes específicos . Um carro só precisa de um motor, ele não se importa com o que implementa a funcionalidade básica do motor. Ou seja, sua Carclasse não está vinculada a dependência de implementação específica; é "injetado" em outro lugar, potencialmente em tempo de execução.

Este exemplo específico de carro usa o subtipo de DI chamado "Injeção de construtor", o que significa apenas que a dependência foi entregue como um argumento de construtor. Você também pode usar um setEngine(Engine a)método para "Injeção de setter" e assim por diante, mas esses subtipos me parecem pedantes.

Um pouco mais longe, no entanto, muitas estruturas de DI fornecem o clichê para conectar um monte dessas coisas com referências mais abstratas.

É isso aí.


0

Não sou especialista, pois só comecei a usar DI nos últimos dois anos, mas alguns dos temas / funcionalidades úteis dos contêineres de DI que notei são (os quais não considero produtos de composição / polimorfismo (mas posso ser corrigido nisso):

  • hub central de criação de objetos
  • fornecer singletons por segmento
  • técnicas orientadas a aspectos como interceptação

0

Além do DI, há uma configuração de composição de classe no aplicativo raiz (em vez de configurar usando xml). Não há necessidade de nenhuma estrutura de DI ou IoC, mesmo que elas possam arrumar a configuração da composição de classe, principalmente para grandes projetos. Isso ocorre porque a estrutura DI normalmente vem com um contêiner que implementa recursos adicionais, como a fiação automática, que ajuda a configurar a composição da classe. Você pode ler a entrada do meu blog para extrair meu entendimento sobre este tópico.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.