Utilizando
Sealed Classes
para controle de fluxos
alexrios.github.io
alex.rios@protonmail.com
@alextrending
Alex Rios
Quem sou eu?
Gosto de implementar sistemas embarcados e fazer integrações não usuais.
Me interesso por testabilidade, qualidade e explicitação do código e arquitetura baseadas em Event Sourcing.
Por onde passei até agora
We're Hiring
Agenda
-
O problema com as exceções
-
Sealed Classes
-
Benefícios
-
Seja Exaustivo
-
Variações
-
Adeus exceções?
O problema com as exceções
O que tem de errado com esse código?
Esse código é passível de erros. Você sabe como lidar com as falhas dessa chamada?
Kotlin não te obriga a tratar as exceções pois não existem exceções checadas.
Lendo o código descobrimos que temos que tratar a UserProfileClientException
Agora já sabemos que esse erro receberá o tratamento adequado
-
Ininteligível (try-catch hell)
-
Não é fácil identificar qual método lançou a exceção
-
Tratamos todos os erros possíveis?
-
Fluxo de execução confuso
-
Muitos round-trips no código para descobrir o que esta acontecendo
E se tivéssemos um jeito de modelar o nosso resultado da chamada em um objeto que mapeasse o sucesso e falha?
Sealed Classes!
Sealed classes
Uma sealed class dentro de um when força todos os casos a serem tratados.
Em um exemplo mais complexo
Benefícios
Menos erros. Código agora é type-safe.
O fluxo dos dados agora não é ambíguo, garantido pelo compilador.
Legibilidade. Com uma boa nomenclatura e o uso do when é muito simples acompanhar o código.
Rastreabilidade & Previsibilidade. A execução não tem saltos inesperados. O fluxo pode ser lido de cima para baixo.
4 pontos sobre uma modelagem baseada em resultado
Ter o objeto Error reflete melhor a realidade e eleva seu tratamento a first class citizen da logica de negocio.
1.
O objeto pode ser passado pelas chamadas
(ex. Pode ser colocado em uma fila).
2.
Melhor suporte ao idioma funcional. requestUserProfile() sempre retorna um valor.
Nada alem disso pode acontecer (como lançar uma exceção).
Isso torna mais fácil o uso de lambdas e a collections API.
3.
Processamento em Batch e paralelização de multiples requests fica mais fácil de implementar (comparado com a versão com métodos lançando exceções).
4.
Result Class Genérica
Seja Exaustivo
Para tirar máximo proveito das sealed classes, when deve ser usado como uma expressão
Forçando a exaustão
Variações
Alguns casos sem estado
Enum quando todos os casos forem sem estado
Utilizando propriedades nos objetos de resultado
Imagine a implementação da função
Adeus exceções?
Não!
Ainda precisamos de exceções.
Usar result classes para tudo pode deixar seu código difícil de lidar quando você tem que propagar esses objetos em varias camadas.
Sugestão
Use result objects para chamadas externas (chamadas a uma API).
Ou algo mais sofisticado que apenas logar.
Sugestão
Use exceções quando vc não tem nenhuma ação a tomar.
ex: log, database fora do ar.
Use o que funciona para você e para sua equipe
Não é uma formula mágica de controlar estado e fluxos. É apenas mais uma opção.
alexrios.github.io
alex.rios@protonmail.com
@alextrending
Obrigado!
Sealed Classes
By Alex Rios
Sealed Classes
- 493