sábado, 23 de fevereiro de 2019

Programação funcional Java - Parte 1: Lambda



Olá, nesse artigo vamos entender como utilizar Programação Funcional em Java, expressões lambda e Interfaces Funcionais.

Utilizamos o termo Programação Funcional (PF) para definir um paradigma de programação que, assim como os outros: Orientação a Objeto (OO) ou Procedural (PE), dita como nossos programas serão construídos e executados. O que diferencia a PF dos demais paradigmas é que, nesse modelo de programação, as ações serão determinadas por uma sequência de constantes e funções.

Para entender como aplicar PF em Java vou utilizar como exemplo uma calculadora simples, apenas com as principais operações matemáticas: Adição, Subtração, Multiplicação e Divisão.
O primeiro passo é identificar como utilizamos uma calculadora para efetuar uma operação, por exemplo: Calcular a soma dos números 50 e 60:

50 + 60 = 110

Abstraindo esse comportamento, teremos:

valor1 (operador) valor2 = resultado

Ou seja, mantendo os operandos constantes (valor1 = 50 e valor2 = 60) e alterando o operador [+, -, *, /] obteremos como resultado, respectivamente: 110, -10, 3000 e 0.83.



Definição dos papéis:

O operador tem o papel de efetuar os números (valor1 e valor2) e o cálculo do resultado da operação será definido pela junção desses três parâmetros: valor1, valor2 e operador.

Vamos agora iniciar a construção do projeto:

1º Passo: No Java, precisamos é definir o papel do operador que, como já foi dito, irá efetuar os dois operandos. Faremos isso por meio de uma interface que irei chamar de Operador.
Veja o código da interface Operador:


Observe no código acima que colocamos um único método efetua na interface Operador que, por ser um método abstrato, necessita ser implementado em outra classe para funcionar. Iremos discutir mais sobre a implementação desse método nos próximos passos da construção do projeto.

2º Passo: Para consumir a interface criada no passo anterior, vou adicionar ao projeto a classe Calculadora e nela, inserir o método calcula que irá receber os três elementos necessários para o cálculo (valo1, valor2, operador): 


Perceba que o método calcula reproduz o comportamento da calculadora sem que nenhuma operação tenha sido definida até o momento. No próximo passo, iremos inserir as operações desejadas ao projeto, mudando assim o comportamento do método calcula de acordo com essas operações.

3º Passo: Vamos finalmente criar uma classe para testar a calculadora, iniciando pela operação de Adição.
Para evitar a criação de uma classe separada que implemente a interface Operador vou utilizar o conceito de Classe Interna Anônima:


4º Passo: Se você estiver utilizando o Netbeans, ao concluir o código acima irá perceber que o próprio IDE irá sugerir a substituição da classe interna anônima por uma expressão lambda. Com a introdução dos operadores lambda a partir do Java 8, a implementação de classes internas anônimas foi bastante facilitada, chegando a substituir várias linhas de instrução por poucas palavras (em alguns casos 2 palavras são suficientes). Veja a seguir a completa substituição de uma classe interna anônima por uma expressão lambda:



Atenção: Para substituir uma classe interna anônima por uma expressão lambda, a interface deverá conter apenas 1 (um) método abstrato.  Opcionalmente, para garantir essa estrutura, anote a interface com @FunctionalInterface.

1Copie os argumentos de entrada do método efetua:
Os argumentos de entrada do método deverão estar no início da expressão lambda, antes do operador “->”;

2Copie o corpo do método implementado:
O corpo do método fica após o operador “->”. Caso possua mais de uma linha, coloque o código entre chaves {...}

Dica: Por inferência, o Java consegue detectar o tipo dos argumentos do método, dispensando assim sua declaração. Caso o método possua apenas 1 (um) argumento de entrada, os parênteses também podem ser retirados:


5º Passo: A nossa calculadora já está quase concluída, bastando apenas declarar os operadores restantes:

Dica: Se o operador lambda executa um único método que combina os valore de entra (no nosso caso, a expressão lambda efetua o valor1 com o valor2) podemos utilizar Method Reference no lugar da expressão lambda. Method Reference pode ser utilizado na substituição de métodos de instância ou métodos estáticos. Veja um exemplo para a operação de multiplicação:


Conclusão: Como planejado no início, apenas com o método calcula(...) conseguimos efetuar as 4 operações, bastando apenas trocar a função (adição, subtração, multiplicação e divisão) passada como parâmetro. Outro ponto interessante é que, a partir do Java 8, podemos declarar métodos estáticos em uma Interface, ou seja, se migrarmos o método calcula para a Interface Operador e nela também declararmos as nossas operações, o projeto final fica ainda mais simplificado.


Por hoje é isso. Obrigado por ler este artigo. Até breve!



Nenhum comentário:

Postar um comentário