Resumo-Guia de Artigo "Substituir Throw com Notification Pattern"

Posted . Visible to the public.

Explicação

  • Exception's deveriam ser usadas para exceções de fato, e não para a logica tradicional da aplicação, como é comumente usada em validações
  • No contexto de validações é ruim para o usuário ter de ficar obtendo os erros um a um. É preferível obter uma lista completa de erros logo na primeira tentativa (como ocorre no uso de Notification Pattern)
  • Você deveria se perguntar se ao remover todos os try/catch do código a sua aplicação continuaria rodando como esperado (no "fluxo principal" / "caso ideal"). Caso a resposta seja que não, provavelmente você está usando Exceptions do jeito errado.
  • Existem contextos discutíveis, como validar a obtenção de um arquivo, que pode:
    • Ser um arquivo bem conhecido e parte da base do Linux e que é esperado que sempre existirá, e a falha na obtenção pode ser uma exceção;
    • Ser um arquivo informado pelo usuário, muito passível de erros, e a falha na obtenção deveria ser uma lógica de notificação, e não tratada por exceção.
  • Um outro caso discutível é o uso de uma segunda validação de dados (que já foram validadas previamente no fluxo do código) mas que podem ser tratadas por exceção apenas como uma forma de garantir que um erro de programação não passou por engano (o esperado é realmente que esta exceção nunca seja atingida)

Implementar Notification Pattern:

  • Uma simples lista de Strings de erros seria suficiente. Mas terceirizar uma classe para as notificações deixa a lógica mais legível
  • Esta refatoração começa com a separação de 2 métodos:
    • validation() devolve o objeto de Notification "populado" com os erros;
    • check() usa o validation() para o obter o objeto de Notification e no caso do hasErrors() ser true lança a exceção exatamente como antes.
    • Desta forma a estrutura original se mantem no check() e você pode ir refatorando os usos desta validação para passar a trabalhar diretamente com o objeto Notification devolvido pelo novo comportamento validation()
void check() {
	Notification val = validation()
	if (val.hasErrors())
		throw new IllegalArgumentException(val.errorMessage())
}
Notification validation() {
	Notification note = new Notification()
	if (/*validacao*/) note.addError("mensagem de erro");
	return note
}
  • É importante lembrar que numa refatoração se deve garantir que o comportamento original seja mantido no código final, portanto:
    • Nesta refatoração em específico se deve observar se o atual código que recebe a atual mensagem de exceção se preocupa diretamente com o conteúdo da mensagem. A intenção é decidir se no check() a exceção será lançada com erros.get(0) ou erros.join(', ') no retorno de val.errorMessage()

Sugestões adicionais genéricas de refatoração:

Bruno Vieira
Last edit
Bruno Vieira
Posted by Bruno Vieira to ZeroGlosa (2016-03-22 18:00)