Pergunta

A inversão de controle (ou IoC) pode ser bastante confusa quando encontrada pela primeira vez.

  1. O que é?
  2. Qual problema isso resolve?
  3. Quando é apropriado usar e quando não?
Foi útil?

Solução

Os padrões de Inversão de Controle (IoC) e Injeção de Dependência (DI) tratam da remoção de dependências do seu código.

Por exemplo, digamos que seu aplicativo tenha um componente de editor de texto e você queira fornecer verificação ortográfica.Seu código padrão seria algo assim:

public class TextEditor {

    private SpellChecker checker;

    public TextEditor() {
        this.checker = new SpellChecker();
    }
}

O que fizemos aqui cria uma dependência entre o TextEditor e a SpellChecker.Em um cenário de IoC, faríamos algo assim:

public class TextEditor {

    private IocSpellChecker checker;

    public TextEditor(IocSpellChecker checker) {
        this.checker = checker;
    }
}

No primeiro exemplo de código estamos instanciando SpellChecker (this.checker = new SpellChecker();), o que significa que TextEditor classe depende diretamente do SpellChecker aula.

No segundo exemplo de código, estamos criando uma abstração tendo o SpellChecker classe de dependência em TextEditor assinatura do construtor (não inicializando a dependência na classe).Isso nos permite chamar a dependência e depois passá-la para a classe TextEditor assim:

SpellChecker sc = new SpellChecker; // dependency
TextEditor textEditor = new TextEditor(sc);

Agora o cliente que cria o TextEditor classe tem o controle sobre qual SpellChecker implementação a ser usada porque estamos injetando a dependência no TextEditor assinatura.

Este é apenas um exemplo simples, há uma boa série de artigos por Simone Busoli que explica com mais detalhes.

Outras dicas

Inversão de controle é o que você obtém quando o programa retorna, por exemplo.como um programa gui.

Por exemplo, em um menu old school, você pode ter:

print "enter your name"
read name
print "enter your address"
read address
etc...
store in database

controlando assim o fluxo de interação do usuário.

Em um programa GUI ou algo assim, dizemos:

when the user types in field a, store it in NAME
when the user types in field b, store it in ADDRESS
when the user clicks the save button, call StoreInDatabase

Então agora o controle está invertido...em vez de o computador aceitar a entrada do usuário em uma ordem fixa, o usuário controla a ordem em que os dados são inseridos e quando os dados são salvos no banco de dados.

Basicamente, qualquer coisa com um loop de eventos, retornos de chamada ou gatilhos de execução se enquadram nesta categoria.

O que é inversão de controle?

Se você seguir estas duas etapas simples, terá feito a inversão de controle:

  1. Separado o que-parte de tarefas de quando-parte de tarefas.
  2. Garanta que quando parte sabe como pequeno quanto possível sobre o que papel;e vice versa.

Existem diversas técnicas possíveis para cada uma dessas etapas com base na tecnologia/linguagem que você está usando para sua implementação.

--

O inversão parte da Inversão de Controle (IoC) é confusa;porque inversão é o termo relativo.A melhor maneira de entender a IoC é esquecer essa palavra!

--

Exemplos

  • Manipulação de eventos.Manipuladores de eventos (parte do que fazer) - Gerando eventos (parte do quando fazer)
  • Interfaces.Cliente do componente (parte quando fazer) -- Implementação da interface do componente (parte o que fazer)
  • Fixação xUnit.Setup e TearDown (parte do que fazer) - os frameworks xUnit chamam para Setup no início e TearDown no final (parte de quando fazer)
  • Padrão de design do método de modelo.parte do que fazer do método de modelo - implementação da subclasse primitiva parte do que fazer
  • Métodos de contêiner DLL em COM.DllMain, DllCanUnload, etc (parte sobre o que fazer) - COM/OS (parte quando fazer)

A inversão de controles trata da separação de preocupações.

Sem COI:Você tem um computador portátil computador e você acidentalmente quebra a tela.E, caramba, você descobre que o mesmo modelo de tela de laptop não existe em nenhum lugar do mercado.Então você está preso.

Com COI:Você tem um Área de Trabalho computador e você acidentalmente quebra a tela.Você descobre que pode pegar quase qualquer monitor de desktop do mercado e funciona bem com seu desktop.

Seu desktop implementa IoC com sucesso neste caso.Ele aceita diversos tipos de monitores, enquanto o laptop não, precisa de uma tela específica para ser consertado.

Inversão de Controle, (ou IoC), é sobre obtendo liberdade (Você se casa, perde a liberdade e está sendo controlado.Você se divorciou, acabou de implementar a Inversão de Controle.Isso é o que chamamos de “desacoplado”.Um bom sistema de computador desencoraja relacionamentos muito próximos.) mais flexibilidade (A cozinha do seu escritório só serve água limpa da torneira, que é a sua única opção quando quiser beber.Seu chefe implementou a Inversão de Controle montando uma nova máquina de café.Agora você tem a flexibilidade de escolher água da torneira ou café.) e menos dependência (Seu parceiro tem emprego, você não tem emprego, você depende financeiramente do seu parceiro, então você é controlado.Você encontra um emprego, implementou a Inversão de Controle.Um bom sistema de computador incentiva a independência.)

Quando você usa um computador desktop, você é escravo (ou, digamos, controlado).Você tem que sentar diante de uma tela e olhar para ela.Usando o teclado para digitar e usando o mouse para navegar.E um software mal escrito pode escravizá-lo ainda mais.Se você substituir seu desktop por um laptop, você inverteu um pouco o controle.Você pode facilmente pegá-lo e se movimentar.Portanto, agora você pode controlar onde está com seu computador, em vez de ser controlado por ele.

Ao implementar a Inversão de Controle, um consumidor de software/objeto obtém mais controles/opções sobre o software/objetos, em vez de ser controlado ou ter menos opções.

Com as ideias acima em mente.Ainda sentimos falta de uma parte fundamental da COI.No cenário da IoC, o consumidor de software/objeto é um framework sofisticado.Isso significa que o código que você criou não é chamado por você.Agora vamos explicar por que essa forma funciona melhor para uma aplicação web.

Suponha que seu código seja um grupo de trabalhadores.Eles precisam construir um carro.Esses trabalhadores precisam de um local e de ferramentas (uma estrutura de software) para construir o carro.A tradicional a estrutura do software será como uma garagem com muitas ferramentas.Portanto, os próprios trabalhadores precisam fazer um plano e usar as ferramentas para construir o carro.Construir um carro não é um negócio fácil, será muito difícil para os trabalhadores planearem e cooperarem adequadamente.A moderno A estrutura do software será como uma fábrica de automóveis moderna, com todas as instalações e gerentes instalados.Os trabalhadores não precisam fazer nenhum plano, os gestores (parte do framework, são as pessoas mais inteligentes e fizeram o plano mais sofisticado) vão ajudar na coordenação para que os trabalhadores saibam quando fazer o seu trabalho (o framework chama seu código).Os trabalhadores só precisam ser flexíveis o suficiente para usar quaisquer ferramentas que os gerentes lhes forneçam (usando Injeção de Dependência).

Embora os trabalhadores entreguem o controle do gerenciamento do projeto no nível superior aos gerentes (a estrutura).Mas é bom ter alguns profissionais ajudando.Este é o conceito de IoC que realmente vem.

Aplicativos Web modernos com arquitetura MVC dependem da estrutura para fazer o roteamento de URL e colocar controladores em funcionamento para a chamada da estrutura.

Injeção de Dependência e Inversão de Controle estão relacionadas.A injeção de dependência está no micro nível e a inversão de controle está no macro nível.Você tem que comer cada mordida (implementar DI) para terminar uma refeição (implementar IoC).

Antes de usar a Inversão de Controle, você deve estar bem ciente do fato de que ela tem seus prós e contras e deve saber por que usá-la se o fizer.

Prós:

  • Seu código é desacoplado para que você possa trocar facilmente implementações de uma interface por implementações alternativas
  • É um forte motivador para codificação em interfaces em vez de implementações
  • É muito fácil escrever testes de unidade para o seu código porque ele não depende de nada além dos objetos que aceita em seus construtores/setters e você pode inicializá-los facilmente com os objetos certos isoladamente.

Contras:

  • A IoC não apenas inverte o fluxo de controle em seu programa, mas também o turva consideravelmente.Isso significa que você não pode mais simplesmente ler seu código e pular de um lugar para outro porque as conexões que normalmente estariam em seu código não estão mais no código.Em vez disso, está nos arquivos de configuração XML ou nas anotações e no código do seu contêiner IoC que interpreta esses metadados.
  • Surge uma nova classe de bugs onde você erra sua configuração XML ou suas anotações e pode gastar muito tempo descobrindo por que seu contêiner IoC injeta uma referência nula em um de seus objetos sob certas condições.

Pessoalmente, vejo os pontos fortes do IoC e gosto muito deles, mas tendo a evitar o IoC sempre que possível, porque ele transforma seu software em uma coleção de classes que não constituem mais um programa "real", mas apenas algo que precisa ser montado por Configuração XML ou metadados de anotação e cairiam (e desmoronariam) sem eles.

  1. Artigo da Wikipédia.Para mim, inversão de controle é transformar seu código escrito sequencialmente em uma estrutura de delegação.Em vez de seu programa controlar tudo explicitamente, seu programa configura uma classe ou biblioteca com certas funções a serem chamadas quando certas coisas acontecem.

  2. Ele resolve a duplicação de código.Por exemplo, antigamente você escreveria manualmente seu próprio loop de eventos, pesquisando as bibliotecas do sistema em busca de novos eventos.Hoje em dia, na maioria das APIs modernas, você simplesmente informa às bibliotecas do sistema em quais eventos você está interessado e elas avisam quando eles acontecem.

  3. A inversão de controle é uma maneira prática de reduzir a duplicação de código e, se você estiver copiando um método inteiro e alterando apenas uma pequena parte do código, considere lidar com isso com inversão de controle.A inversão de controle é facilitada em muitas linguagens por meio do conceito de delegados, interfaces ou até mesmo ponteiros de função brutos.

    Não é apropriado usá-lo em todos os casos, porque o fluxo de um programa pode ser mais difícil de acompanhar quando escrito desta forma.É uma maneira útil de projetar métodos ao escrever uma biblioteca que será reutilizada, mas deve ser usada com moderação no núcleo do seu próprio programa, a menos que realmente resolva um problema de duplicação de código.

Mas acho que você tem que ter muito cuidado com isso.Se você usar esse padrão em excesso, criará um design muito complicado e um código ainda mais complicado.

Como neste exemplo com TextEditor:se você tiver apenas um corretor ortográfico, talvez não seja realmente necessário usar o IoC?A menos que você precise escrever testes unitários ou algo assim...

De qualquer forma:seja razoável.O padrão de design é boas práticas mas não a Bíblia para ser pregada.Não cole em todos os lugares.

Suponha que você seja um objeto.E você vai a um restaurante:

Sem COI:você pede "maçã" e sempre recebe maçã quando pede mais.

Com COI:Você pode pedir "fruta".Você pode obter frutas diferentes cada vez que for servido.por exemplo, maçã, laranja ou melancia.

Então, obviamente, o IoC é preferido quando você gosta das variedades.

IoC/DI para mim está enviando dependências para os objetos de chamada.Super simples.

A resposta não técnica é ser capaz de trocar o motor de um carro antes de ligá-lo.Se tudo estiver conectado corretamente (a interface), você está bem.

  1. A inversão de controle é um padrão usado para desacoplar componentes e camadas do sistema.O padrão é implementado através da injeção de dependências em um componente quando ele é construído.Essas dependências são geralmente fornecidas como interfaces para maior dissociação e para dar suporte à testabilidade.Contêineres IoC/DI como Castle Windsor, Unity são ferramentas (bibliotecas) que podem ser usadas para fornecer IoC.Essas ferramentas fornecem recursos estendidos além do simples gerenciamento de dependências, incluindo tempo de vida, AOP/Interceptação, política, etc.

  2. a.Alivia um componente de ser responsável pelo gerenciamento de suas dependências.
    b.Fornece a capacidade de trocar implementações de dependência em diferentes ambientes.
    c.Permite que um componente seja testado por meio de simulação de dependências.
    d.Fornece um mecanismo para compartilhar recursos em um aplicativo.

  3. a.Crítico ao fazer desenvolvimento orientado a testes.Sem IoC pode ser difícil testar, porque os componentes em teste estão altamente acoplados ao resto do sistema.
    b.Crítico ao desenvolver sistemas modulares.Um sistema modular é um sistema cujos componentes podem ser substituídos sem necessidade de recompilação.
    c.Crítico se houver muitas preocupações transversais que precisam ser abordadas, especialmente em um aplicativo empresarial.

Vou escrever meu entendimento simples desses dois termos:

For quick understanding just read examples*

Injeção de Dependência (DI):
Injeção de dependência geralmente significa passar um objeto do qual o método depende, como parâmetro para um método, em vez de fazer com que o método crie o objeto dependente.
O que isso significa na prática é que o método não depende diretamente de uma implementação específica;qualquer implementação que atenda aos requisitos pode ser passada como parâmetro.

Com esses objetos, informe suas dependências.E a primavera o disponibiliza.
Isso leva ao desenvolvimento de aplicativos fracamente acoplados.

Quick Example:EMPLOYEE OBJECT WHEN CREATED,
              IT WILL AUTOMATICALLY CREATE ADDRESS OBJECT
   (if address is defines as dependency by Employee object)

Contêiner de inversão de controle (IoC):
Esta é uma característica comum das estruturas, COI gerencia objetos java
– da instanciação à destruição através do seu BeanFactory.
-Os componentes Java que são instanciados pelo contêiner IoC são chamados de beans, e os O contêiner IoC gerencia o escopo de um bean, eventos de ciclo de vida e quaisquer recursos AOP para o qual foi configurado e codificado.

QUICK EXAMPLE:Inversion of Control is about getting freedom, more flexibility, and less dependency. When you are using a desktop computer, you are slaved (or say, controlled). You have to sit before a screen and look at it. Using keyboard to type and using mouse to navigate. And a bad written software can slave you even more. If you replaced your desktop with a laptop, then you somewhat inverted control. You can easily take it and move around. So now you can control where you are with your computer, instead of computer controlling it.

Ao implementar a Inversão de Controle, um consumidor de software/objeto obtém mais controles/opções sobre o software/objetos, em vez de ser controlado ou ter menos opções.

A inversão de controle como diretriz de projeto serve aos seguintes propósitos:

Há uma dissociação entre a execução de uma determinada tarefa e a implementação.
Cada módulo pode se concentrar naquilo para o qual foi projetado.
Os módulos não fazem suposições sobre o que outros sistemas fazem, mas confiam em seus contratos.
A substituição de módulos não tem efeito colateral em outros módulos
Vou manter as coisas abstratas aqui. Você pode visitar os links a seguir para uma compreensão detalhada do tópico.
Uma boa leitura com exemplo

Explicação detalhada

Respondendo apenas a primeira parte.O que é?

Inversão de controle (IoC) significa criar instâncias de dependências primeiro e depois instâncias de uma classe (opcionalmente injetando-as por meio do construtor), em vez de criar primeiro uma instância da classe e depois a instância da classe criando instâncias de dependências.Assim, inversão de controle inverte o fluxo de controle do programa. Em vez de o controle do receptor o fluxo de controle (ao criar dependências), o chamador controla o fluxo de controle do programa.

Por exemplo, a tarefa nº 1 é criar um objeto.Sem o conceito IOC, a tarefa nº 1 deveria ser realizada pelo programador. Mas com o conceito IOC, a tarefa nº 1 seria realizada pelo contêiner.

Resumindo, o controle é invertido do programador para o contêiner.Então, é chamado de inversão de controle.

Encontrei um bom exemplo aqui.

Digamos que marcamos uma reunião em algum hotel.

Muitas pessoas, muitas jarras de água, muitos copos de plástico.

Quando alguém quer beber, ela enche o copo, bebe e joga o copo no chão.

Depois de uma hora ou algo assim, temos um chão coberto de copos plásticos e água.

Vamos inverter o controle.

A mesma reunião no mesmo local, mas em vez de copos de plástico temos um garçom com um copo de vidro (Singleton)

e ela sempre oferece bebidas aos convidados.

Quando alguém quer beber, ela pega o copo do garçom, bebe e devolve ao garçom.

Deixando de lado a questão da higiene, a última forma de controle do processo de bebida é muito mais eficaz e econômica.

E é exatamente isso que o Spring (outro contêiner IoC, por exemplo:Guice) faz.Em vez de deixar o aplicativo criar o que precisa usando uma nova palavra-chave (pegando um copo de plástico), o contêiner Spring IoC sempre oferece ao aplicativo a mesma instância (singleton) do objeto necessário (copo de água).

Pense em você como organizador dessa reunião.Você precisa enviar uma mensagem à administração do hotel que

os membros da reunião precisarão de um copo de água, mas não de um pedaço de bolo.

Exemplo:-

public class MeetingMember {

    private GlassOfWater glassOfWater;

    ...

    public void setGlassOfWater(GlassOfWater glassOfWater){
        this.glassOfWater = glassOfWater;
    }
    //your glassOfWater object initialized and ready to use...
    //spring IoC  called setGlassOfWater method itself in order to
    //offer to meetingMember glassOfWater instance

}

Links Úteis:-

Eu concordo com NilObject, mas gostaria de acrescentar:

se você estiver copiando um método inteiro e alterando apenas uma pequena parte do código, considere lidar com isso com inversão de controle

Se você estiver copiando e colando código, quase sempre estará fazendo algo errado.Codificado como o princípio de design Uma vez e apenas uma vez.

Parece que a coisa mais confusa sobre "IoC", a sigla e o nome que representa, é que é um nome muito glamoroso - quase um nome barulhento.

Precisamos realmente de um nome para descrever a diferença entre programação processual e programada por eventos?OK, se precisarmos, mas será que precisamos escolher um novo nome "maior que a vida" que confunda mais do que resolva?

IoC trata de inverter a relação entre seu código e o código de terceiros (biblioteca/estrutura):

  • No desenvolvimento normal de software, você escreve o principal() método e chamar métodos de "biblioteca". Você estão no controle :)
  • Na IoC, a "estrutura" controla principal() e chama seus métodos.O Estrutura está no controle :(

DI (Injeção de Dependência) trata de como o controle flui no aplicativo.O aplicativo de desktop tradicional tinha fluxo de controle de seu aplicativo (método main()) para outras chamadas de método de biblioteca, mas com o fluxo de controle DI é invertido, essa estrutura cuida de iniciar seu aplicativo, inicializá-lo e invocar seus métodos sempre que necessário.

No final você sempre ganha :)

Inversão de controle é quando você vai ao supermercado e sua esposa te dá a lista de produtos para comprar.

Em termos de programação, ela passou uma função de retorno de chamada getProductList() para a função que você está executando - doShopping().

Permite ao usuário da função definir algumas partes dela, tornando-a mais flexível.

Uma explicação escrita muito simples pode ser encontrada aqui

http://binstock.blogspot.in/2008/01/excellent-explanation-of-dependency.html

Diz -

"Qualquer aplicativo não trivial é composto de duas ou mais classes que colaboram entre si para realizar alguma lógica de negócios.Tradicionalmente, cada objeto é responsável por obter suas próprias referências aos objetos com os quais colabora (suas dependências).Ao aplicar DI, os objetos recebem suas dependências no tempo de criação por alguma entidade externa que coordena cada objeto no sistema.Em outras palavras, as dependências são injetadas nos objetos."

A Inversão de Controle é um princípio genérico, enquanto a Injeção de Dependência realiza esse princípio como um padrão de design para a construção de gráficos de objetos (ou seja,a configuração controla como os objetos fazem referência entre si, em vez de o próprio objeto controlar como obter a referência para outro objeto).

Olhando para a Inversão de Controle como um padrão de design, precisamos observar o que estamos invertendo.A injeção de dependência inverte o controle de construção de um gráfico de objetos.Se for dito em termos leigos, a inversão de controle implica mudança no fluxo de controle do programa.Por exemplo.No aplicativo autônomo tradicional, temos o método principal, de onde o controle é passado para outras bibliotecas de terceiros (no caso, usamos a função da biblioteca de terceiros), mas através da inversão do controle o controle é transferido do código da biblioteca de terceiros para o nosso código , pois estamos contratando o serviço de biblioteca terceirizada.Mas há outros aspectos que precisam ser invertidos dentro de um programa – por exemplo.invocação de métodos e threads para executar o código.

Para aqueles interessados ​​em mais detalhes sobre Inversão de Controle, foi publicado um artigo delineando uma imagem mais completa da Inversão de Controle como um padrão de design (OfficeFloor:usando padrões de escritório para melhorar o design de software http://doi.acm.org/10.1145/2739011.2739013 com uma cópia gratuita disponível para download em http://www.officefloor.net/about.html).

O que se identifica é a seguinte relação:

Inversão de controle (para métodos) = Injeção de dependência (estado) + Injeção de continuação + Injeção de thread

Resumo da relação acima para Inversão de Controle disponível - http://dzone.com/articles/inversion-of-coupling-control

Encontrei um exemplo muito claro aqui o que explica como o 'controle é invertido'.

Código clássico (sem injeção de dependência)

Aqui está como um código que não usa DI funcionará aproximadamente:

  • O aplicativo precisa de Foo (por exemploum controlador), então:
  • Aplicativo cria Foo
  • Aplicativo chama Foo
    • Foo precisa de Bar (ex.um serviço), então:
    • Foo cria Bar
    • Foo liga para o Bar
      • Bar precisa do Bim (um serviço, um repositório,…), então:
      • Bar cria Bim
      • Bar faz alguma coisa

Usando injeção de dependência

Aqui está como um código usando DI funcionará aproximadamente:

  • A aplicação precisa do Foo, que precisa do Bar, que precisa do Bim, então:
  • Aplicativo cria Bim
  • Aplicativo cria Bar e dá Bim
  • O aplicativo cria Foo e fornece Bar
  • Aplicativo chama Foo
    • Foo liga para o Bar
      • Bar faz alguma coisa

O controle das dependências é invertido de quem está sendo chamado para quem está chamando.

Que problemas isso resolve?

A injeção de dependência facilita a troca com as diferentes implementações das classes injetadas.Durante o teste de unidade, você pode injetar uma implementação fictícia, o que torna o teste muito mais fácil.

Ex:Suponha que seu aplicativo armazene o arquivo enviado pelo usuário no Google Drive. Com DI, o código do seu controlador pode ficar assim:

class SomeController
{
    private $storage;

    function __construct(StorageServiceInterface $storage)
    {
        $this->storage = $storage;
    }

    public function myFunction () 
    {
        return $this->storage->getFile($fileName);
    }
}

class GoogleDriveService implements StorageServiceInterface
{
    public function authenticate($user) {}
    public function putFile($file) {}
    public function getFile($file) {}
}

Quando seus requisitos mudam, digamos, em vez do GoogleDrive, você será solicitado a usar o Dropbox.Você só precisa escrever uma implementação de dropbox para StorageServiceInterface.Você não precisa fazer nenhuma alteração no controlador, desde que a implementação do Dropbox siga o StorageServiceInterface.

Durante o teste, você pode criar uma simulação para StorageServiceInterface com a implementação fictícia, onde todos os métodos retornam nulo (ou qualquer valor predefinido de acordo com seus requisitos de teste).

Em vez disso, se você tivesse a classe controladora para construir o objeto de armazenamento com o new palavra-chave como esta:

class SomeController
{
    private $storage;

    function __construct()
    {
        $this->storage = new GoogleDriveService();
    }

    public function myFunction () 
    {
        return $this->storage->getFile($fileName);
    }
}

Quando você quiser mudar com a implementação do Dropbox você deve substituir todas as linhas onde new O objeto GoogleDriveService é construído e usa o DropboxService.Além disso, ao testar a classe SomeController, o construtor sempre espera a classe GoogleDriveService e os métodos reais desta classe são acionados.

Quando é apropriado e quando não?Na minha opinião, você usa DI quando pensa que existem (ou podem haver) implementações alternativas de uma classe.

Programação falando

IoC em termos fáceis:É o uso da Interface como forma de especificar algo (como um campo ou parâmetro) como um curinga que pode ser usado por algumas classes.Permite a reutilização do código.

Por exemplo, digamos que temos duas classes: Cachorro e Gato.Ambos compartilham as mesmas qualidades/estados:idade, tamanho, peso.Então, em vez de criar uma classe de serviço chamada DogService e CatService, posso criar um único chamado Serviço Animal que permite usar Dog e Cat somente se eles usarem a interface Animal.

No entanto, pragmaticamente falando, há alguns retrocessos.

a) A maioria dos desenvolvedores não sabe como usá-lo.Por exemplo, posso criar uma classe chamada Cliente e Posso criar automaticamente (usando as ferramentas do IDE) uma interface chamada Cliente.Portanto, não é raro encontrar uma pasta repleta de classes e interfaces, sejam elas reutilizadas ou não.Chama-se BLOATED.Algumas pessoas poderiam argumentar que “talvez no futuro possamos usá-lo”.:-|

b) Tem algumas limitações.Por exemplo, vamos falar sobre o caso de Cachorro e Gato e quero adicionar um novo serviço (funcionalidade) apenas para cães.Digamos que eu queira calcular o número de dias que preciso para treinar um cachorro (trainDays()), para gato não adianta, gato não pode ser treinado (estou brincando).

b.1) Se eu adicionar trainDays() para o serviço Serviço Animal então também funciona com gatos e não é válido de forma alguma.

b.2) Posso adicionar uma condição em trainDays() onde avalia qual classe é usada.Mas isso quebrará completamente o COI.

b.3) Posso criar uma nova classe de serviço chamada DogService apenas pela nova funcionalidade.Porém, aumentará a capacidade de manutenção do código porque teremos duas classes de serviço (com funcionalidade semelhante) para Cachorro e isso é ruim.

Eu gosto desta explicação: http://joelabrahamsson.com/inversion-of-control-an-introduction-with-examples-in-net/

Começa de forma simples e também mostra exemplos de código.

enter image description here

O consumidor, X, precisa da classe consumida, Y, para realizar algo.Tudo isso é bom e natural, mas X realmente precisa saber que usa Y?

Não é suficiente que X saiba que usa algo que possui o comportamento, os métodos, propriedades etc. de Y, sem saber quem realmente implementa o comportamento?

Ao extrair uma definição abstrata do comportamento usado por X em Y, ilustrado como I abaixo, e deixar o consumidor X usar uma instância disso em vez de Y, ele pode continuar a fazer o que faz sem precisar conhecer os detalhes sobre Y.

enter image description here

Na ilustração acima, Y implementa I e X usa uma instância de I.Embora seja bem possível que X ainda use Y, o interessante é que X não sabe disso.Ele apenas sabe que usa algo que implementa I.

Leia o artigo para obter mais informações e descrição de benefícios como:

  • X não depende mais de Y
  • Mais flexível, a implementação pode ser decidida em tempo de execução
  • Isolamento da unidade de código, testes mais fáceis

...

Entendo que a resposta já foi dada aqui.Mas ainda acho que alguns princípios básicos sobre a inversão de controle devem ser discutidos aqui detalhadamente para futuros leitores.

A Inversão de Controle (IoC) foi construída sobre um princípio muito simples chamado Princípio de Hollywood.E diz isso,

Não ligue para nós, nós ligaremos para você

O que isso significa é que não vá a Hollywood para realizar o seu sonho, mas se você for digno, Hollywood o encontrará e realizará o seu sonho.Quase invertido, né?

Agora, quando discutimos sobre o princípio do COI, costumamos esquecer de Hollywood.Para a IoC, tem que haver três elementos, uma Hollywood, você e uma tarefa como realizar o seu sonho.

Em nosso mundo de programação, Hollywood representam uma estrutura genérica (pode ser escrita por você ou por outra pessoa), você representa o código do usuário que você escreveu e a tarefa represente o que você deseja realizar com seu código.Agora você nunca mais acionará sua tarefa sozinho, nem no IoC!Em vez disso, você projetou tudo de tal forma que sua estrutura acionará sua tarefa para você.Assim, você construiu uma estrutura reutilizável que pode transformar alguém em herói ou outro em vilão.Mas esse quadro está sempre no comando, sabe quando escolher alguém e esse alguém só sabe o que quer ser.

Um exemplo da vida real seria dado aqui.Suponha que você queira desenvolver uma aplicação web.Assim, você cria uma estrutura que irá lidar com todas as coisas comuns que um aplicativo da web deve lidar, como lidar com solicitações http, criar menus de aplicativos, servir páginas, gerenciar cookies, disparar eventos, etc.

E então você deixa alguns ganchos em sua estrutura onde você pode colocar mais códigos para gerar menus personalizados, páginas, cookies ou registrar alguns eventos do usuário, etc.Em cada solicitação do navegador, sua estrutura será executada e executará seus códigos personalizados, se estiver conectado, e depois os enviará de volta ao navegador.

Então, a ideia é bem simples.Em vez de criar um aplicativo de usuário que controlará tudo, primeiro você cria uma estrutura reutilizável que controlará tudo, depois escreve seus códigos personalizados e conecta-os à estrutura para executá-los a tempo.

Laravel e EJB são exemplos de tais frameworks.

Referência:

https://martinfowler.com/bliki/InversionOfControl.html

https://en.wikipedia.org/wiki/Inversion_of_control

A inversão de controle consiste na transferência do controle da biblioteca para o cliente.Faz mais sentido quando falamos de um cliente que injeta (passa) um valor de função (expressão lambda) em uma função de ordem superior (função de biblioteca) que controla (altera) o comportamento da função de biblioteca.Um cliente ou estrutura que injeta dependências de biblioteca (que carregam comportamento) em bibliotecas também pode ser considerado IoC

  1. Então número 1 acima. O que é inversão de controle?

  2. A manutenção é a primeira coisa que resolve para mim.Garante que estou usando interfaces para que duas classes não sejam íntimas uma da outra.

Ao usar um contêiner como o Castle Windsor, ele resolve ainda melhor os problemas de manutenção.Ser capaz de trocar um componente que vai para um banco de dados por um que usa persistência baseada em arquivo sem alterar uma linha de código é incrível (mudança de configuração, pronto).

E quando você entra nos genéricos, fica ainda melhor.Imagine ter um editor de mensagens que recebe registros e publica mensagens.Não se importa com o que publica, mas precisa de um mapeador para transformar algo de um registro em uma mensagem.

public class MessagePublisher<RECORD,MESSAGE>
{
    public MessagePublisher(IMapper<RECORD,MESSAGE> mapper,IRemoteEndpoint endPointToSendTo)
    {
      //setup
    }
}

Eu escrevi isso uma vez, mas agora posso injetar muitos tipos nesse conjunto de código se publicar diferentes tipos de mensagens.Também posso escrever mapeadores que pegam registros do mesmo tipo e os mapeiam para mensagens diferentes.Usar DI com genéricos me deu a capacidade de escrever muito pouco código para realizar muitas tarefas.

Ah, sim, existem preocupações de testabilidade, mas elas são secundárias em relação aos benefícios do IoC/DI.

Definitivamente, estou adorando IoC/DI.

3.Torna-se mais apropriado no momento em que você tem um projeto de médio porte e um pouco mais complexo.Eu diria que se torna apropriado no momento em que você começa a sentir dor.

Criar um objeto dentro da classe é chamado de acoplamento forte, o Spring remove essa dependência seguindo um padrão de design (DI/IOC).Em qual objeto da classe é passado no construtor em vez de criar na classe.Além disso, damos uma variável de referência de superclasse no construtor para definir uma estrutura mais geral.

Usando IoC você não está atualizando seus objetos.Seu contêiner IoC fará isso e gerenciará a vida útil deles.

Resolve o problema de ter que alterar manualmente cada instanciação de um tipo de objeto para outro.

É apropriado quando você possui funcionalidades que podem mudar no futuro ou que podem ser diferentes dependendo do ambiente ou configuração utilizada.

Para entender o conceito, Inversão de Controle (IoC) ou Princípio de Inversão de Dependência (DIP) envolve duas atividades:abstração e inversão.A injeção de dependência (DI) é apenas um dos poucos métodos de inversão.

Para ler mais sobre isso você pode ler meu blog Aqui

  1. O que é?

É uma prática em que você permite que o comportamento real venha de fora dos limites (Classe em Programação Orientada a Objetos).A entidade limite conhece apenas a abstração (por exemplo, interface, classe abstrata, delegado em Programação Orientada a Objetos) dela.

  1. Que problemas isso resolve?

Em termos de programação, a IoC tenta resolver o código monolítico tornando-o modular, desacoplando várias partes dele e tornando-o testável em unidade.

  1. Quando é apropriado e quando não?

É apropriado na maioria das vezes, a menos que você tenha uma situação em que deseja apenas código monolítico (por exemplo, um programa muito simples).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top