Category Archives: Orientação Objeto

Inversão de Controle (IoC)

Senhoras e Senhores leitores desse blog, preparem-se para um momento marcante desse…blog….

[rufam os tambores]

Vamos falar sobre Inversão de Controle e Injeção de Dependência !!

[Fogos de artifícios explodem, papéis picados e coloridos caem sobre a multidão e a multidão vai ao delírio!]

Ao ler isso, você pode cair em 3 situações

1- Você vê as pessoas vibrando em volta de você, mas ainda não sabe o porque de tanta euforia. Você ainda não tem certeza do que venha ser Injeção de Dependência. Então, limpe os papeis picado que cai sobre seus ombros e vamos fazer parte dessa multidão que vai ao delírio, com todos sabendo exatamente do que estamos falando!

2- Você vibra com um soco no ar! E diga-se por passagem, Já era tempo !!

3- Você já sabe tudo sobre isso e zomba aqueles que estão vibrando, pulando, como se fosse uma grande novidade. Ficará só mais um momento nesse blog para vangloriar-se de sua superioridade! Noobs!

Por que toda a galera foi ao delírio ?

Para explicar o conceito de Inversão de Controle, vamos a um exemplo simples.

Vejamos o Controller abaixo

public class ClientesController : Controller
{
      public ActionResult Index()
      {
            var cliente = new Cliente();
            var todosClientes = cliente.TodosClientes();
            return View(todosClientes);
      }
 }
 

O código acima compila e executa sem nenhum erro, isto é, supondo que temos um método chamado TodosClientes que nos retornaria do banco de dados todos os nossos clientes cadastrados.

What’s the Big Deal ? O que há de errado então ?

Bom, eu, particularmente, não diria que há algo errado, mas diria que está fora dos padrões de qualidade. Minha opinião!

O problema no código acima é o que chamamos de Alto Acoplamento (lembrando que sempre buscamos desenvolver um código de Baixo Acoplamento e Alta Coesão).

Fazendo uma rápida análise no código acima, podemos listar as seguintes responsabilidades da classe ClientesController:

1- Ela instancia um Cliente.
2- Está buscando todos os clientes da base.
3- Passa todos esses clientes para uma view e retornar a view.

Agora vamos listar o que há de mal nessa classe.

1- Ela cria uma instância de um Cliente
Ao instanciar um cliente na nossa classe ClientesController criamos uma dependência da classe Cliente, o que faz com que qualquer alteração no cliente, afete diretamente o nosso controller, o que certamente prejudicaria a manutenção do código.

2- Está buscando todos os clientes da base de dados
Vamos pensar no teste unitário nesse caso. Os testes unitários devem ser independentes de conexão. Ao testarmos a classe Controller, o que aconteceria?

Temos uma forte dependência com o nossa conexão com o banco de dados para para que seja possível o retorno dos clientes, o que impossibilitaria mockar o Cliente.

Como Resolver ?

E é aí que entra a Inversão de Controle, em outras palavras, vamos inverter o controle na classe ClientesController, tirando qualquer responsabilidade vinculada à classe Cliente, e passaremos isso para uma outra classe, ou interface.

Mas de que Modo? Como faço essa inversão de controle ?

Injeção de Dependência!

Existem 3 maneiras de fazermos a nossa famosa injeção de dependência

1- Via Construtores
2- Nas Propriedades
3- Via Interface:

Então vamos praticar cada um deles, editando o nosso código inicial

Primeiro vamos injetar dependência com Construtores

public class ClientesController : Controller
{
     private ICliente _cliente;
     public ClientesController(ICliente cliente)
     {
          _cliente = cliente;
     }
     public ActionResult Index()
     {
          var todosClientes = _cliente.TodosClientes();
          return View(todosClientes);
     }
}

Com esse código, você já ganha um novo amigo!, o cara lá do teste! Easypeasy fazer amizades !!

Agora vamos ver como ficaria a injeção de dependência utilizando as propriedades, Getters e Setters

public class ClientesController
{
    private ICliente _cliente;
    public ClientesController()
    {
    }
    public ICliente Cliente
    {
        get  {
           if (_cliente != null)
               return _cliente;
        }
        set  {
           meuPedido = value;
        }
    }
 }


Bom, e temos alguma restrição de quando usar um e quando usar outro método ?

Pode-se dizer que a injeção de dependência por propriedades é preferível quando os construtores não possuem nenhum argumento, o que faz com que seja bem fácil você criar o objeto em produção e testá-lo.

Mas vamos eleger um vencedor aqui então!

Meu voto vai para a injeção de dependência via construtores.

Por Que ?

Uai, porque com isso eu garanto a ordem de inicialização, o que previne uma dependência circular em meu projeto, enquanto que com injeção de propriedades você não saberia bem ao certo em qual ordem você deve chamar cada get/set.

Bom, outras opiniões, serão bem vindas nos coments !!

até a próxima !

Advertisements

Métricas de Coesão Baseado na Orientação a Objeto – Parte 1

Pessoal, como esse é o meu primeiro post no blog, gostaria de começar a falar um pouco sobre a tão falada Programação Orientada a Objeto.

Quando comecei a minha jornada na área de programação como estagiário há alguns anos atrás, e não tinha conhecimentos sólidos em Orientação a Objeto, mas estava encarregado de codificar algumas partes de um sistema de grande porte para um cliente chave em uma fábrica de software.

Ao final da minha tarefa, meu código foi revisto por um analista mais experiente e ouvi ele dizer que meu código estava com baixa coesão e alto acoplamento, e pela minha falta de experiência na época, fiquei sem entender o que ele quis dizer.

Atualmente, meu maior foco é deixar o código de acordo com os paradigmas da Orientação a Objeto.

Mas como saber se meu código está coeso e desacoplado ?

E é aí que entram as métricas que verificarão a coesão e acoplamento do nosso código. Sabemos que, métricas são quantitativas, portanto o resultado da análise será um valor, que veremos logo abaixo o que ele significará para nós.

Como são várias as métricas existentes e cada uma com suas particularidades, nesse primeiro post vou tratar de falar apenas da métrica chamada Lack Coehsion of Methods (LCOM), mas falarei nos posts seguintes de outras métricas muito utilizadas no mercado (por esse motivo esse post está classificado como ‘Parte 1’).

A métrica LCOM é definida por ser uma contagem dos pares de métodos na qual a similaridade é 0 (zero).¹

Como calcular a coesão do meu código de acordo com a métrica LCOM ?

A fórmula do cálculo é

LCOM = P = NP – Q

Onde:
P é o número de métodos que não compartilham atributos
Q é o número de métodos que compartilham atributos

NP é dado pela função
M! / 2! . (M – 2)!

sendo M o número de métodos existentes na classe

Exemplo de classes

Exemplo de classes

Podemos ver nessa imagem 4 métodos que são representados pelos quadrados, e 4 atributos que são representados pelos círculos, sendo que o atributo a1 é compartilhado pois o método m1 e m2 o acessam.

LCOM = (M! / 2! . (M – 2)) – 1
LCOM = (4.3.2.1 / 2.1 . (4-2)) – 1
LCOM = (24 / 4) – 1
LCOM = 6 – 1
LCOM = 5

Quanto maior o valor encontrado, menor a coesão, e isso indica um design mal elaborado.

Referências
¹ http://www.computing.dcu.ie/~renaat/ca421/LCOM.html
² http://www.ece.rutgers.edu/~marsic/books/SE/instructor/slides/lec-16%20Metrics-Cohesion.ppt