SlideShare uma empresa Scribd logo
Globalcode – Open4education
Trilha .NET
Gabriel Schade Cardoso
Software Engineer | Mestre em Computação Aplicada | Professor | Escritor
Globalcode – Open4education
Mestre em computação aplicada
Microsoft Certified Solutions Associate (MCSA)
Desenvolvedor, Professor e Revisor
Autor dos livros
Gabriel Schade Cardoso
Globalcode – Open4education
Agenda
Contexto
Abordagens Funcionais
Refatoração
Globalcode – Open4education
Programação Funcional
Quem aqui sabe o que é isso?
Isso é o ícone da F# Foundation
F# também é .NET
Globalcode – Open4education
Problemas comuns
Quem aqui sabe o que é isso?
ArgumentNullException
DomainException
Essa nem existe na linguagem, mas eu já vi TANTO
Globalcode – Open4education
Como essas duas coisas estão
conectadas?
Programação funcional é bem diferente de
programação orientada à objetos;
É um paradigma diferente;
Globalcode – Open4education
Como essas duas coisas estão
conectadas?
Ao aprender um novo paradigma, você aprende uma
nova forma de ver os problemas.
Globalcode – Open4education
Vamos ao problema do null
Veja este método:
O que ele tem de errado?
Globalcode – Open4education
Vamos ao problema do null
Ele é um método mentiroso;
A assinatura dele me garante que ele irá retornar um
usuário, mas se o Id for inválido?
Globalcode – Open4education
Vamos ao problema do null
Veja este método:
O que é um User option?
Globalcode – Open4education
Vamos ao problema do null
O método avisa que talvez ele retorne um usuário;
Mas como isso muda nossa implementação?
Globalcode – Open4education
Vamos ao problema do null
Mas isso não é só um null check obrigatório?
Quase, mas causa erro de compilação.
O erro acontece porque o tipo option é um value container,
encapsulando qualquer tipo.
Globalcode – Open4education
Value Containers
Já ouviram falar?
Globalcode – Open4education
Um container pode ser visto como um envelope ou uma caixa
que circunda um dado, incluindo-o em algum contexto
específico.
Lidamos com este tipo de valor o tempo todo:
List;
Array;
Task;
Nullable.
Value Containers
Globalcode – Open4education
Imagine o seguinte cenário: você possui um dado do tipo
inteiro e precisa somá-lo com o valor 3.
Value Containers
Globalcode – Open4education
E se este número estiver em um array?
Value Containers
Globalcode – Open4education
Não podemos realizar a soma com o mesmo valor, isso por
conta do contexto que o cerca.
Por isso, comumente temos uma função para remover o valor
de seu contexto.
Value Containers
Globalcode – Open4education
No caso do array o indexador remove o valor do contexto.
Value Containers
Globalcode – Open4education
No caso do option utilizamos o pattern matching ao invés do
indexador.
Podemos nos aproveitar deste conceito para criar novos
objetos e classes que armazenam valores sob um determinado
contexto.
Que tal criar um Option para o C#?
Value Containers
Globalcode – Open4education
Option<T>
O tipo não pode ser nulo nunca;
Precisamos de um pattern matching;
Não deixaremos o programador acessar a informação, caso ela
esteja no estado inválido;
Globalcode – Open4education
Globalcode – Open4education
Option
Globalcode – Open4education
Option<T>
Ainda não temos um substituto para o pattern matching;
Para fazer isso vamos usar uma HOF (High order function)
Globalcode – Open4education
Option<T>
Globalcode – Open4education
Option<T>
O toque final é criar o cast implícito, com isso nem precisamos
criar manualmente o tipo Option.
Dentro da struct Option:
Globalcode – Open4education
Option<T>
Globalcode – Open4education
Option<T>
O toque final é criar o cast implícito, com isso nem precisamos
criar manualmente o tipo Option.
Dentro da struct Option:
Globalcode – Open4education
Value Containers
E se precisássemos de validações mais complexas?
Existem mais value containers além do Option!
Either<TLeft, TRight>
...
Vamos refatorar uma funcionalidade que atualiza um usuário
Globalcode – Open4education
Reparem nesta estrutura de código:
Atualizando um usuário
Globalcode – Open4education
Atualizando um usuário
Reparem nesta estrutura de código:
Void?
Globalcode – Open4education
Atualizando um usuário
Reparem nesta estrutura de código:
Void?
Globalcode – Open4education
Atualizando um usuário
Reparem nesta estrutura de código:
Sempre Ok?
Globalcode – Open4education
Atualizando um usuário
Reparem nesta estrutura de código:
E quando as coisas dão errado?
Como as funções estão implementadas?
Globalcode – Open4education
Atualizando um usuário
Globalcode – Open4education
Atualizando um usuário
Globalcode – Open4education
Atualizando um usuário
Globalcode – Open4education
Atualizando um usuário
Como as exceções não estão sendo tratadas, acabamos
sempre retornando um erro 500.
Este HTTP code não deve ser utilizado para isso, precisamos
retornar um 400 (bad request).
Onde colocar esse tratamento?
Globalcode – Open4education
Globalcode – Open4education
Atualizando um usuário
Não... Só não.
Vamos tentar produzir esse resultado, mas sem try-catches:
Globalcode – Open4education
Atualizando um usuário
Globalcode – Open4education
Atualizando um usuário
Precisamos continuar enviando o resultado para frente, mesmo
se algo deu errado, dessa forma não quebramos o fluxo de
código.
Vamos fazer mais um container, dessa vez para representar um
resultado para a continuação de uma operação.
Globalcode – Open4education
Atualizando um usuário
Globalcode – Open4education
Atualizando um usuário
Notem que as propriedades de nossa classe só possuem um
método get, ou seja, todas elas são readonly;
Precisamos de construtores!
Globalcode – Open4education
Atualizando um usuário
Em um construtor
temos apenas os
dados de sucesso, no
outro os de falha.
Globalcode – Open4education
Com nosso novo container já é possível retornar um resultado!
Vamos começar adaptando a função Update!
Criando um novo tipo
Globalcode – Open4education
Return em dois locais diferentes?
Ainda usamos try-catch?
Existem erros que podem
acontecer no banco;
O usuário pode não existir no
banco;
Criando um novo tipo
Globalcode – Open4education
Vamos separar melhor;
Criando um método para verificar se o usuário existe
Criando um novo tipo
Globalcode – Open4education
Para não termos que criar o Continuation, vamos apelar de
novo, lembram do cast implícito?
Criando um novo tipo
Globalcode – Open4education
Com o cast implícito podemos simplesmente retornar os
valores;
Criando um novo tipo
Globalcode – Open4education
Com o cast implícito podemos simplesmente retornar os
valores;
Criando um novo tipo
Globalcode – Open4education
Com o cast implícito podemos simplesmente retornar os
valores;
Criando um novo tipo
Globalcode – Open4education
Agora vamos resolver os problemas do método Validate;
Primeiro vamos utilizar a própria linguagem para gerar a lista
de erros:
Criando um novo tipo
Globalcode – Open4education
Vamos utilizar Continuation aqui também:
Criando um novo tipo
Globalcode – Open4education
Agora vamos voltar ao Controller!
Criando um novo tipo
Globalcode – Open4education
Remover o try-catch;
Exibir mensagens de
erros tratadas.
Criando um novo tipo
Globalcode – Open4education
Criando um novo tipo
Globalcode – Open4education
Criando um novo tipo
Globalcode – Open4education
Criando um novo tipo
Globalcode – Open4education
Criando um novo tipo
Globalcode – Open4education
Atualizando um usuário
Parece uma composição!
Só que ruim.
A solução ainda está bem estranha, com vários If’s e
comparações.
E se encapsulássemos isso de uma forma que a composição
faça mais sentido?
Globalcode – Open4education
Atualizando um usuário
Vamos criar os métodos Then e Catch;
Eles recebem uma função por parâmetro e retornam uma
estrutura de continuação!
Globalcode – Open4education
Atualizando um usuário
O método Catch faz a mesma coisa, mas com a comparação
contrária:
Globalcode – Open4education
Atualizando um usuário
Como a própria comparação está na estrutura, não precisamos
mais dos IFs!
Globalcode – Open4education
Atualizando um usuário
O Update precisa de 2 parâmetros!!
Globalcode – Open4education
Atualizando um usuário
É só usar Lambda!
Globalcode – Open4education
Atualizando um usuário
Neste ponto você já deve ter percebido que estamos sempre
atualizando o continuation, certo?
Mas como o próprio método já o retorna, podemos utilizar
uma sintaxe encadeada!
Globalcode – Open4education
Atualizando um usuário
Globalcode – Open4education
Atualizando um usuário
Também podemos utilizar um match para extrair o resultado
do Continuation!
Globalcode – Open4education
Atualizando um usuário
Saímos daqui:
Globalcode – Open4education
Atualizando um usuário
Chegamos aqui:
Globalcode – Open4education
Atualizando um usuário
Chegamos aqui:
Globalcode – Open4education
Atualizando um usuário
Outros exemplos:
Globalcode – Open4education
Atualizando um usuário
Outros exemplos:
Globalcode – Open4education
Nuget  Tango
Github.com/gabrielschade/Tango
Open source
E-book gratuito em português e inglês
https://gabrielschade.github.io/tango-br
Globalcode – Open4education
https://gabrielschade.github.io/tango-br
https://docs.microsoft.com/en-us/dotnet/fsharp/get-start
/
http://fsharp.org/
https://fsharpforfunandprofit.com
Referências
/gabrielschade
/gabrielschade
/gabrielschade
/gabrielschade
https://gabrielschade.github.io

Mais conteúdo relacionado

Abordagem Funcional para Gerenciamento de Erros em .NET