Vinicius Quaiato

{tecnologia, conceitos, negócios, idéias, práticas, .NET, ruby, osx, ios e algo mais}

Inversão de Controle (Inversion of Control / IoC)


Fala galera, beleza?Escolhi falar de Inversão de Controle pois recentemente precisei utilizar este conceito em uma nova implementação no trabalho. E também percebi o quão necessário é que os desenvolvedores conheçam este conceito/padrão/técnica.Bom vamos lá. Inversão de Controle, como o próprio nome diz significa que o controle de execução do programa/código muda. Eu gosto de pensar também que o controle de conhecimento do código muda.Como isso?De uma forma bem simplista podemos dizer por exemplo que o controle que uma classe/método possui acaba sendo mudado, invertido, para algum outro ponto do código.Vamos ver um exemplo de código:

public class Pedido{

  private EnviadorDeEmails enviador = null;

  public void Gravar(){
      //Vai ao banco de dados
      this.enviador = new EnviadorDeEmails("smtp","conta@empresa.com","senha");
      this.enviador.EnviarEmail("Novo Pedido Criado!");
  }
}

Esta classe possui não somente o controle do fluxo de execução do programa, mas ela possui o controle sobre o código, e isso significa alto acoplamento e responsabilidades demais. Ela sabe exatamente como criar um EnviadorDeEmails, e controla também os parâmetros de configuração do smtp.Ainda que ela recuperasse estes valores do arquivo .config ou do banco de dados, ela teria esse controle.Como poderíamos, de forma simples, inverter este controle? Uma maneira simples e eficaz seria utilizando um Factory Method estático, na própria classe EnviadorDeEmails, vejamos como ficaria:

public
static EnviadorDeEmails ObterEnviadorDeEmails(){    //valores podem vir do .config    //podem vir do banco    //quem consome esta classe não sabe    //ela não tem controle sobre isso
return new EnviadorDeEmails("smtp", "email@empresa.com", "senha");
    }

E então nossa classe Pedido ficaria assim:

public class Pedido{

private EnviadorDeEmails enviador = null;

public void Gravar()    {        //Vai ao banco de dados        this.enviador = EnviadorDeEmails.ObterEnviadorDeEmails();
    this.enviador.EnviarEmail("Novo Pedido Criado!");
    }
}

É isso pessoal.Esta é uma das muitas maneiras de realizar Inversão de Controle.Como Martin Fowler explica, uma outra forma de IoC seria utilizando Template Methods. A classe abstrata define o fluxo de controle, mas o que será executado é o código cliente quem define, e assim o controle é novamente invertido.Poderíamos fazer isso utilizando Injeção de Dependências, e Contêiners de IoC/DI.Nos próximos posts falaremos mais sobre Injeção de Dependências e Contêiners de IoC.Martin Fowler tem um texto clássico sobre este assunto: http://martinfowler.com/bliki/InversionOfControl.html Abraços.Vinicius Quaiato.

Voltar

Fork me on GitHub