.NET

25 set, 2014

Programação Orientada a Objetos em 10 lições práticas – Parte 10

Publicidade

Apresentando o padrão IoC – Inversão de Controle

Neste artigo você vai aprender o que é o padrão IoC ou Inversão de Controle e saber por que você deve programar para uma abstração e não para uma implementação.

Objetivo: Apresentar os conceitos do padrão Ioc apresentando seus recursos e mostrando seus benefícios.

Recursos usados: Visual Studio 2012 Express for Windows desktop

Nota: Neste momento já se encontra disponível a versão 2013

É importante salientar que a ferramenta usada é gratuita, não possui restrições e é totalmente funcional. Ao fazer o download da ferramenta, você também pode baixar o pacote de idioma para localizar o produto para a língua portuguesa.

Problema: Você precisa programar para uma abstração e não para uma implementação.

Conceitos básicos – O padrão IoC

Adotar boas práticas no processo de desenvolvimento de software deixou de ser um diferencial para ser uma questão de sobrevivência. O cenário atual aponta para uma grande demanda por software de qualidade com prazos e custos cada vez mais reduzidos. Não há mais lugar para desculpas, como falta de recursos ou de tempo. Ou você oferece o que o mercado deseja, ou está fora.

Usar padrões é uma das atitudes que beneficia o projeto, pois facilita o reuso, os testes e permite uma melhor manutenção do produto.

Este artigo apresenta o padrão inversão de controle (IoC), também conhecido como injeção de dependência (há uma certa polêmica quanto essa correspondência).

Se você nunca ouviu falar em inversão de controle (IoC), saiba que este padrão é muito usado em projetos orientados a objeto e utiliza conceitos como interface, herança e polimorfismo. Ele também tem como objetivo reduzir o acoplamento, facilitar o reuso e os testes no projeto de software.

Antes de iniciar, creio que seria bom lembrar algumas definições importantes que serão usadas neste artigo:

Nota: Veja detalhes sobre o assunto no meu artigo.

1. Objeto

  • É a representação de um modelo abstrato definido em uma classe;
  • É uma instância de uma classe;
  • O estado de um objeto é o conjunto de suas propriedades;
  • Cada objeto tem o seu próprio estado;
  • O comportamento de um objeto são as funções (métodos) que afetam suas propriedades e/ou as propriedades de outros objetos.

2. Classe

  • É o modelo a partir do qual os objetos serão criados;
  • Um objeto é uma instância de uma classe;
  • Uma classe define as propriedades e comportamento que cada uma de suas instâncias (objetos) possuirá;
  • Classes podem se comunicar em entre si trocando informações(dados, parâmetros, controles etc).

3. Acoplamento

  • É o nível de dependência/conhecimento que pode existir entre as classes;
  • Uma classe com acoplamento fraco não é dependente de muitas classes para fazer o que ele tem que fazer;
  • Uma classe com acoplamento forte depende de muitas outras classes para fazer o seu serviço;
  • Uma classe com acoplamento forte é mais difícil de manter, de entender e de ser reusada.

4. Coesão

  • É o nível de integralidade interna de uma classe (veja o principio da responsabilidade única – SRP);
  • A coesão mede o grau que um classe ou seus métodos fazem sentido; ou seja, quão claro é o entendimento do que a classe ou método possui;
  • Uma classe com alta coesão possui responsabilidades bem definidas e são difíceis de serem desmembradas em outras classes;
  • Uma classe com baixa coesão possui muitas responsabilidades, geralmente que pertencem a outras classes, e podem ser facilmente desmembradas em outras classes;
  • Uma classe com baixa coesão é difícil de entender, manter e reusar.

Portanto, quanto mais forte o acoplamento e mais baixa a coesão de uma classe, mais difícil ela será de entender, manter e ser reusada.

Agora vamos a parte prática, onde irei mostrar como podemos aplicar o padrão de inversão de controle.

Aplicando a Inversão de Controle – IoC

Abaixo temos o código da classe A, que usa a classe B:

Public Class A

    Private b As B
                                             
    Public Sub New()
         b = New B()
         Console.WriteLine("Foi criado o objeto b")
    End Sub

End Class

A classe A acessa diretamente a classe B, criando uma instância da classe no seu construtor.

Vamos supor que a classe B é uma classe concreta com um construtor padrão. O código da classe B é dado a seguir:

Public Class B

    Public Sub New()
        Console.WriteLine("Foi criada uma instância da classe B")
    End Sub
End Class

Neste exemplo, temos um forte acoplamento entre a classe A e a classe B, pois quem controla a criação de uma instância da classe B é a classe A, que é responsável por obter uma referência da classe B.

Qualquer alteração que ocorra na classe B vai afetar diretamente a classe A, pois esta possui uma referência a classe B.

Como fazer com que a classe A não seja afetada pelas mudanças feitas na classe B, sem perder a referência para a classe B? Como diminuir o acoplamento entre a classe A e a classe B? Podemos fazer isso usando o padrão inversão de controle (IoC).

Nota: Existem diversos frameworks que usam o padrão IoC e que efetuam a injeção de dependência.

Vemos abaixo a classe A ajustada para usar o padrão IoC:

Public Class A
   Private b As B

   Public Sub New()
   End Sub

   Public Sub setB(ByVal b As B)  
       Me.b = b
   End Sub
End Class

Agora, a classe A obtém uma referência da classe B usando o método setB(). Dessa forma, a classe A pode obter uma referência da classe B sem saber como a classe B é instanciada. A classe B, por sua vez, pode ser uma interface, classe abstrata ou até mesmo uma classe concreta.

Não existe mais nenhum acoplamento entre a classe A e a classe B e qualquer alteração feita na classe B não afeta a classe A – e vice-versa.

Se houver uma alteração no método da classe B, a classe A deverá ser alterada também; mas a criação do objeto B não tem a sua implementação na classe A. Podemos usar o método setB() para injetar o objeto B.

Perceba que todos os conceitos aqui abordados usam princípios básicos da programação orientada a objetos e que não existe segredo algum. Então, quando se ouve falar que “O framework XYZ usa a injeção de dependência…”, ele está basicamente usando os recursos que expomos neste artigo e que são os pilares da programação orientada a objetos:

  • Programe sempre para uma interface;
  • Prefira usar a composição a herança;
  • Obedeça o princípio da responsabilidade única;(SRP-Single Responsability Principle).

Obs: O “Unity Application Block”, do “Enterprise Library 4.0”, é um container de inversão de controle baseado na biblioteca “ObjectBuilder2” do “Entreprise Library” e que foi lançado como uma alternativa às já tradicionais bibliotecas “Spring.NET” (uma versão da famosa biblioteca Spring do mundo Java), “Castle Windsor”, “StructureMap”, “ObjectBuilder” etc.

Concluímos, assim, o mini curso VB .NET – Programação Orientada a Objetos em 10 lições práticas, onde apresentamos os fundamentos do paradigma da programação orientada a objetos com foco na implementação para a linguagem VB .NET.

Foram dez passos de uma longa jornada que trilhamos a cada dia quando abrimos a nossa ferramenta de trabalho e fazemos aquilo que gostamos: programar, desenvolver, aprender, enfim, viver.

Lembre-se da regra máxima: “Programe para um a interface e não para uma implementação”.