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

  • 484