Isso é um antipadrão? É uma prática aceitável?
try {
//do something
} catch (Exception e) {
try {
//do something in the same line, but being less ambitious
} catch (Exception ex) {
try {
//Do the minimum acceptable
} catch (Exception e1) {
//More try catches?
}
}
}
anti-patterns
exception-handling
Senhor Smith
fonte
fonte
Respostas:
Às vezes, isso é inevitável, principalmente se o seu código de recuperação gerar uma exceção.
Não é bonito, mas às vezes não há alternativas.
fonte
Eu não acho que seja um antipadrão, apenas amplamente utilizado.
A maioria das tentativas aninhadas é realmente evitável e feia para o inferno, geralmente o produto de desenvolvedores juniores.
Mas há momentos em que você não pode evitar.
Além disso, você precisará de um bool extra em algum lugar para indicar a falha na reversão ...
fonte
A lógica é boa - em algumas situações, pode fazer todo o sentido tentar uma abordagem de fallback, que pode experimentar eventos excepcionais ... portanto, esse padrão é praticamente inevitável.
No entanto, sugiro o seguinte para melhorar o código:
attemptFallbackMethod
eattemptMinimalRecovery
.finally
bloco pode fazer mais sentido - geralmente é o caso de qualquer coisa que pareça "código de limpeza de recursos"fonte
Está bem. Uma refatoração a considerar é colocar o código em seu próprio método e usar saídas antecipadas para obter sucesso, permitindo que você escreva as diferentes tentativas de fazer algo no mesmo nível:
Depois de dividi-lo assim, você pode pensar em agrupá-lo em um padrão de estratégia.
Em seguida, basta usar o
TrySeveralThingsStrategy
, que é um tipo de estratégia composta (dois padrões pelo preço de um!).Uma grande ressalva: não faça isso a menos que suas estratégias sejam suficientemente complexas ou que você possa usá-las de maneira flexível. Caso contrário, você está usando algumas linhas de código simples com uma pilha enorme de orientação desnecessária a objetos.
fonte
Não acho que seja automaticamente um antipadrão, mas eu o evitaria se encontrasse uma maneira mais fácil e limpa de fazer a mesma coisa. Se a linguagem de programação em que você está trabalhando tiver uma
finally
construção, isso poderá ajudar a limpar isso, em alguns casos.fonte
Não é um antipadrão em si, mas um padrão de código que informa que você precisa refatorar.
E é bem fácil, você só precisa conhecer uma regra prática que está escrevendo não mais do que um bloco try no mesmo método. Se você conhece bem escrever códigos relacionados juntos, geralmente é apenas copiar e colar cada bloco try com seus blocos catch e colá-lo dentro de um novo método e, em seguida, substituir o bloco original por uma chamada para esse método.
Esta regra é baseada na sugestão de Robert C. Martin em seu livro 'Clean Code':
Um exemplo rápido de "pseudo-java". Suponha que tenhamos algo assim:
Podemos refatorar cada tentativa de captura e, nesse caso, cada bloco de tentativa e captura tenta a mesma coisa, mas em locais diferentes (como conveniente: D), temos apenas que copiar e colar um dos blocos de tentativa e captura e fazer um método dele .
Agora usamos isso com o mesmo objetivo de antes.
Espero que ajude :)
fonte
Certamente está diminuindo a legibilidade do código. Eu diria que, se você tiver chance , evite aninhar tentativas.
Se você precisar aninhar tentativas, sempre pare por um minuto e pense:
eu tenho a chance de combiná-los?
devo simplesmente extrair a parte aninhada em um novo método? O código será muito mais limpo.
É óbvio se você precisar aninhar três ou mais níveis de try-catchs, em um único método, que é um sinal claro de tempo para refatoração.
fonte
Eu já vi esse padrão no código de rede e, na verdade, faz sentido. Aqui está a ideia básica, no pseudocódigo:
Basicamente, é uma heurística. Uma tentativa fracassada de conexão pode ser apenas uma falha na rede, mas se isso acontecer duas vezes, isso provavelmente significa que a máquina com a qual você está tentando se conectar está inacessível. Provavelmente, existem outras maneiras de implementar esse conceito, mas elas provavelmente seriam ainda mais feias do que as tentativas aninhadas.
fonte
Resolvi essa situação assim (try-catch com fallback):
fonte
Eu "tive" que fazer isso em uma classe de teste coincidentemente (JUnit), onde o método setUp () precisava criar objetos com parâmetros de construtor inválidos em um construtor que lançou uma exceção.
Se eu tivesse que fazer a construção de 3 objetos inválidos falhar, por exemplo, precisaria de 3 blocos try-catch, aninhados. Em vez disso, criei um novo método, em que as exceções foram capturadas e o valor de retorno era uma nova instância da classe que eu estava testando quando conseguiu.
Claro, eu só precisava de 1 método porque fiz o mesmo 3 vezes. Pode não ser uma solução tão boa para blocos aninhados que fazem coisas totalmente diferentes, mas pelo menos seu código se tornaria mais legível na maioria dos casos.
fonte
Na verdade, acho que é um antipadrão.
Em alguns casos, você pode querer várias tentativas, mas apenas se NÃO SABER que tipo de erro está procurando, por exemplo:
Se você não sabe o que está procurando, DEVE usar a primeira maneira, que é IMHO, feia e não funcional. Eu acho que o último é muito melhor.
Portanto, se você souber que tipo de erro está procurando, seja específico . Não há necessidade de tentativas aninhadas ou múltiplas dentro do mesmo método.
fonte
Em alguns casos, um Try-Catch aninhado é inevitável. Por exemplo, quando o próprio código de recuperação de erro pode gerar uma exceção. Mas, para melhorar a legibilidade do código, você sempre pode extrair o bloco aninhado em um método próprio. Confira esta postagem no blog para obter mais exemplos sobre blocos aninhados Try-Catch-Finalmente.
fonte
Não há nada mencionado como Anti Pattern em java em qualquer lugar. Sim, chamamos poucas coisas de boas práticas e más práticas.
Se for necessário um bloco try / catch dentro de um bloco catch, você não poderá ajudá-lo. E não há alternativa. Como um bloco de captura não pode funcionar como parte de tentativa se a exceção for lançada.
Por exemplo :
Aqui, no método de exemplo acima, lança exceção, mas o doMethod (usado para manipular exceção de método) até lança exceção. Nesse caso, temos que usar o try catch dentro do try catch.
algo que é sugerido não fazer é ..
fonte