As palavras invert
ou control
não são usadas para definir Inversão de Controle nas definições que eu já vi.
Definições
Wikipedia
inversão de controle (IoC) é uma técnica de programação, expressa aqui em termos de programação orientada a objetos, na qual o acoplamento de objetos é vinculado em tempo de execução por um objeto montador e normalmente não é conhecido em tempo de compilação usando análise estática. ~ http://en.wikipedia.org/wiki/Inversion_of_control
Martin Fowler
Inversão de controle é um padrão comum na comunidade Java que ajuda a conectar contêineres leves ou montar componentes de diferentes projetos em um aplicativo coeso. ~ com base em http://www.martinfowler.com/articles/injection.html (reformulado)
Então, por que Inversão de controle é chamada de Inversão de controle? Que controle está sendo invertido e por quê? Existe uma maneira de definir Inversão de Controle usando a terminologia: inverter e controlar ?
fonte
Respostas:
Digamos que você tenha algum tipo de classe "repositório", e esse repositório é responsável por entregar dados a você a partir de uma fonte de dados.
O repositório pode estabelecer uma conexão com a fonte de dados por si só. Mas e se isso permitisse que você transmitisse uma conexão à fonte de dados através do construtor do repositório?
Ao permitir que o chamador forneça a conexão, você separou a dependência da conexão da fonte de dados da classe do repositório, permitindo que qualquer fonte de dados funcione com o repositório, não apenas aquela especificada pelo repositório.
Você inverteu o controle , entregando a responsabilidade de criar a conexão da classe do repositório para o chamador.
Martin Fowler sugere usar o termo "Injeção de Dependência" para descrever esse tipo de Inversão de Controle, uma vez que Inversão de Controle como um conceito pode ser aplicado de maneira mais ampla do que apenas injetar dependências em um método construtor.
fonte
Não acho que alguém possa explicar melhor do que Martin Fowler, mais abaixo no artigo ao qual você vinculou .
Como ele explica nos parágrafos acima, isso não é exatamente o mesmo que a razão pela qual o termo "Inversão de controle" se originou.
É por isso que ele cunhou o termo "Injeção de Dependência" para cobrir essa implementação específica da Inversão de Controle.
Para esclarecer um pouco: Inversão de controle significa qualquer coisa que inverta a estrutura de controle de um programa do design processual clássico.
Antigamente, um exemplo importante disso era deixar uma estrutura manipular a comunicação entre uma interface do usuário e seu código, em vez de deixar seu código para gerar a interface do usuário diretamente.
Em tempos mais recentes (quando essas estruturas praticamente dominavam, então a questão não era mais relevante), um exemplo estava invertendo o controle sobre a instanciação de objetos.
Fowler e outros decidiram que o termo Inversão de controle cobria muitas técnicas e precisávamos de um novo termo para o exemplo específico de instanciação de objetos (injeção de dependência), mas, no momento em que esse acordo foi feito, a frase "IoC Container "decolou.
Isso atrapalha bastante a água, porque um contêiner de IoC é um tipo específico de Injeção de Dependência, mas a Injeção de Dependência é um tipo específico de Inversão de Controle. É por isso que você está recebendo respostas tão confusas, não importa para onde você olha.
fonte
Aqui estão os programas de fluxo de controle "regulares" geralmente seguidos:
Inversão de controle "inverte" esse controle de fluxo, o que significa que ele vira de cabeça para baixo:
Essa última linha é a mais importante. Em vez de ligar para outra pessoa quando lhe apetecer, alguém a chama quando lhe apetecer.
Um exemplo comum disso são estruturas da web como o Rails. Você define Controladores, mas na verdade não decide quando esses serão chamados. O Rails os chama quando decide que há uma necessidade.
fonte
É sobre quem controla a instanciação de dependências.
Tradicionalmente, quando uma classe / método precisa usar outra classe (dependência), ela é instanciada diretamente pela classe / método. Ele controla suas dependências.
Com Inversion of Control (IoC), o chamador passou na dependência e, portanto, instancia a dependência. O chamador controla as dependências.
O controle de onde uma dependência é instanciada foi invertido - em vez de estar no "fundo", onde está o código que precisa, ele é instanciado no "topo", onde o código que precisa dela está sendo chamado.
fonte
Normalmente, o código de nível superior chama (ou seja, controla) o código de nível inferior. Main () chama function (), function () chama libraryFunction ().
Isso pode ser invertido, para que a função de biblioteca de baixo nível na parte inferior chame funções de nível superior.
Por que você faria isso? Middleware. Às vezes, você deseja controlar o nível superior e o inferior, mas há muito trabalho no meio que você simplesmente não quer fazer. Veja a implementação do quicksort no C stdlib . Você chama quicksort no nível superior. Você entrega a qsort () um ponteiro de função para sua própria função que implementa um comparador no que você quiser. Quando qsort () é chamado, chama essa função comparadora. qsort () está controlando / chamando / dirigindo sua função de alto nível.
fonte
Aqui está uma visão geral simples:
Antigamente, o controle era de propriedade do aplicativo primeiro e do usuário segundo. Se o aplicativo precisasse de algo do usuário, ele parava e perguntava e depois passava para a próxima tarefa. A interação do usuário forneceu principalmente dados, em vez de controlar o que o aplicativo fez a seguir. Isso é um pouco estranho para nós hoje em dia, já que não vemos esse tipo de comportamento com muita frequência.
Se mudarmos isso e oferecermos ao usuário o controle primário, invertemos o controle. Isso significa que, em vez de o usuário esperar o aplicativo dar algo para fazer, o aplicativo fica esperando o usuário dar algo para fazer. As GUIs são um ótimo exemplo disso e praticamente qualquer coisa com um loop de eventos inverteu o controle.
Observe que meu exemplo está no nível superior e que esse conceito de inversão de controle pode ser abstraído para diferentes camadas de controle dentro do aplicativo (ou seja, injeção de dependência). Pode ser por isso que é tão difícil obter uma resposta direta.
fonte
Vamos tentar entender isso através dos dois exemplos.
Exemplo 1
Nos dias anteriores, os aplicativos costumavam gerar prompts de comando para aceitar entradas do usuário, uma após a outra. Hoje, as estruturas de interface do usuário instanciam vários elementos da interface do usuário, percorrem vários eventos desses elementos da interface do usuário (como passar o mouse, clique etc.) e os programas usuário / principal fornecem ganchos (por exemplo, ouvintes de eventos da interface do usuário em Java) para ouvir esses eventos. Portanto, o fluxo principal "controle" do elemento da interface do usuário é movido do programa do usuário para a estrutura da interface do usuário. Nos dias anteriores, estava no programa do usuário.
Exemplo 2
Considere a classe
CustomerProcessor
abaixo:Se eu quiser
processCustomer()
ser independente de qualquer implementaçãogetAllCusts()
, e não apenas a fornecida porSqlCustRepo
, precisarei me livrar da linha:SqlCustRepo custRepo = new SqlCustRepo()
e substituí-la por algo mais genérico, capaz de aceitar vários tipos de implementação, de modo queprocessCustomers()
simplesmente funcione para qualquer implementação fornecida. O código acima (instanciar a classe requeridaSqlCustRepo
pela lógica do programa principal) é uma maneira tradicional e não atinge esse objetivo de se separarprocessCustomers()
da implementação degetAllCusts()
. Na inversão de controle, o contêiner instancia a classe de implementação necessária (conforme especificado por, digamos, configuração xml), injeta-a na lógica principal do programa que é vinculada conforme os ganchos especificados (digamos, por@Autowired
anotação ougetBean()
método na estrutura de primavera).Vamos ver como isso pode ser feito. Considere o código abaixo.
Config.xml
CustRepo.java
JsonCustRepo.java
App.java
Nós também podemos ter
e
e não precisaremos alterar o App.java.
Acima do contêiner (que é a estrutura da primavera) tem a responsabilidade de verificar o arquivo xml, instanciar o bean de tipo específico e injetá-lo no programa do usuário. O programa do usuário não tem controle sobre qual classe é instanciada.
PS: IoC é um conceito genérico e é alcançado de várias maneiras. Os exemplos acima o alcançam por injeção de dependência.
Referência: artigo de Martin Fowler .
fonte