As várias formas de fazer inversão de controle
Como eu já descrevi em um artigo anterior, a
inversão de controle é um padrão de projeto (também chamado Design Pattern) que
prega remover de uma classe o controle (ou responsabilidade) de instanciar
outras classes e passar esse controle (responsabilidade) para um componente
externo do sistema, sendo ele um framework, um container, uma classe, um serviço
e etc.
Inversão de controle por injeção de dependência
A forma mais comum de fazermos a inversão de
controle é por meio da injeção de dependência que é também outro desiign
pattern que visa utilizar uma estrutura de software (container)
para "injetar" as dependências usadas por uma classe em vez de
deixar com essa classe a responsabilidade de instanciá-las (entenda por
dependência como os atributos e métodos
de outras classes ).
Nessa
definição você notou a correlação com a
inversão de controle? Ao injetarmos em uma classe as dependências que ela vai
utilizar (injeção de dependência) por consequência, retiramos dessa mesma
classe o controle de instanciar suas classes dependentes (inversão de
controle). Como dito antes a injeção de dependência é uma forma de se realizar
a inversão de controle.
Exemplo:
Uma classe para processar vendas de carros em uma loja de carros:
public class VendaDeCarro {
private Carro carro = new Carro();
private MySQL mysql = new MySQL();
public void vendeCarro() {
//Todo o código para a venda do produto...
mysql.grava(Carro);
}
}
Veja que nesse exemplo a VendaDeCarro utiliza
as classes MySQL e Carros para registrar os carros vendidos em um banco MySQL,
mas e se a empresa quiser utilizar outro banco de dados para gravar seus dados,
ou passar a vender outro produto além de somente carros? Nesse caso teríamos
que reescrever a classe VendaDeCarro ou criar uma classe para cada novo tipo de
produto vendido.
Mas poderíamos resolver isso facilmente
utilizando a injeção de dependência para criar um código desacoplado e flexível
a mudanças.
public interace Banco {
}
public interface Produto {
}
public class VendaDeProduto {
private Produto produto;
private Banco banco;
public VendaDeProduto(Produto produto, Banco banco) {
this.produto = produto;
this.banco = banco;
}
public void vendeProduto() {
//Todo o código para a venda do produto...
banco.grava(produto);
}
}
Nesse exemplo a classe VendaDeProduto pode
lidar com qualquer classe que implemente as interfaces Produto e Banco, sejam elas
classes que abstraíam produtos como carros, peças, acessórios ou classes que
trabalhem com diferentes bancos de dados com MySQL, Oracle ou etc.
Veja:
VendaDeProduto vendadepeca = new VendaDeProduto(Peca, Oracle);
VendaDeProduto vendadepeca = new VendaDeProduto(Carro, MySQL);
Nesse exemplo a classe VendaDeProduto vai
registrar a venda de uma peça em um banco Oracle e futuramente a venda de um
carro em um banco MySQL.
Mas também é possível fazer inversão de
controle sem injeção de dependência. isso mesmo! É possível fazer inversão de
controle por meio de programação funcional e também por orientação a eventos
críticos.
Inversão de controle por meio de programação funcional
Analise o código a seguir:
public interface Calculo {
public int calcular(int valor);
}
public class Main {
public static void main(String[] args) {
System.out.println("Criação e teste de funçoes lambda");
// Injetei o comportamento de dobrar o valor recebido e imprmí-lo na tela.
Calculo calculo1 = (v) -> {return v*v;};
System.out.println(calculo1.calcular(10));
calculo1 = (v) -> {return v+v;};
System.out.println(calculo1.calcular(10));
}
}
Nesse código primeiramente criamos uma
interface chamada Calculo, essa interface é um tipo de interface chamada
interface funcional.
O que são Interfaces Funcionais?
Interfaces Funcionais são todas as interfaces
que possuem um único método à ser implementados, ou em outras palavras, um
método abstrato. No nosso código, por exemplo, a interface Calculo possuí um
único método que se chama calcular. O compilador consegue reconhecer essas
interfaces e disponibilizá-las para o desenvolvedor trabalhar, por exemplo, com
funções Lambdas.
O que são funções Lambdas?
Uma função lambda é uma função sem declaração,
isto é, não é necessário colocar um nome, um tipo de retorno e o modificador de
acesso. A ideia é que o método seja declarado no mesmo lugar em que será usado.
As funções lambda em Java tem a sintaxe definida como (argumento) ->
(corpo), como mostram o nosso código:
Calculo calculo1 = (v) -> {return v*v;};
calculo1 = (v) -> {return v+v;};
Nesses códigos também podemos ver exemplos de
inversão de controle pois injetamos o comportamento que queríamos para a função
calcular, dessa forma a função Main ficou sem o controle de instanciar as
implementações de Calculo que são utilizadas ao longo do código.
Neste artigo vou me restringir a mostrar
apenas como fazer inversão de controle por Injeção de dependência e por programação
funcional para manter a simplicidade e fácil entendimento do artigo.
Até a próxima :)

Comentários
Postar um comentário