¿Es esto un antipatrón? ¿Es una práctica aceptable?
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
Señor Smith
fuente
fuente
Respuestas:
Esto a veces es inevitable, especialmente si su código de recuperación puede arrojar una excepción.
No es bonito, pero a veces no hay alternativas.
fuente
No creo que sea un antipatrón, simplemente mal utilizado.
La mayoría de las capturas de prueba anidadas son de hecho evitables y desagradables, generalmente el producto de desarrolladores junior.
Pero hay veces que no puedes evitarlo.
Además, necesitará un bool extra en alguna parte para indicar el retroceso fallido ...
fuente
La lógica está bien: puede tener mucho sentido en algunas situaciones probar un enfoque alternativo, que podría experimentar eventos excepcionales ... por lo tanto, este patrón es casi inevitable.
Sin embargo, sugeriría lo siguiente para mejorar el código:
attemptFallbackMethod
yattemptMinimalRecovery
.finally
bloque podría tener más sentido: este suele ser el caso de cualquier cosa que parezca "código de limpieza de recursos"fuente
Está bien. Una refactorización a tener en cuenta es empujar el código a su propio método y usar salidas tempranas para tener éxito, lo que le permite escribir los diferentes intentos de hacer algo al mismo nivel:
Una vez que lo haya desglosado así, podría pensar en envolverlo en un patrón de Estrategia.
Luego, use el
TrySeveralThingsStrategy
, que es una especie de estrategia compuesta (¡dos patrones por el precio de uno!).Una gran advertencia: no hagas esto a menos que tus estrategias sean lo suficientemente complejas, o si quieres poder usarlas de manera flexible. De lo contrario, está cargando una línea de código simple con una gran cantidad de orientación innecesaria a los objetos.
fuente
No creo que sea automáticamente un antipatrón, pero lo evitaría si puedo encontrar una manera más fácil y limpia de hacer lo mismo. Si el lenguaje de programación en el que está trabajando tiene una
finally
construcción, eso podría ayudar a limpiar esto, en algunos casos.fuente
No es un antipatrón per se, sino un patrón de código que le indica que necesita refactorizar.
Y es bastante fácil, solo tiene que conocer una regla general que no está escribiendo más que un bloque de prueba en el mismo método. Si sabe bien escribir código relacionado, generalmente solo está copiando y pegando cada bloque try con sus bloques catch y pegándolo dentro de un nuevo método, y luego reemplace el bloque original con una llamada a este método.
Esta regla general se basa en la sugerencia de Robert C. Martin de su libro 'Clean Code':
Un ejemplo rápido de "pseudo-java". Supongamos que tenemos algo como esto:
Entonces podríamos refactorizar cada try try y, en este caso, cada bloque try-catch intenta lo mismo pero en diferentes ubicaciones (qué conveniente: D), solo tenemos que copiar y pegar uno de los bloques try-catch y hacer un método. .
Ahora usamos esto con el mismo propósito que antes.
Espero que eso ayude :)
fuente
Seguramente está disminuyendo la legibilidad del código. Yo diría que si tienes oportunidad , entonces evita anidar trampas.
Si tiene que anidar capturas de prueba, deténgase siempre por un minuto y piense:
¿Tengo la oportunidad de combinarlos?
¿Debería simplemente extraer la parte anidada en un nuevo método? El código será mucho más limpio.
Es obvio si tiene que anidar tres o más niveles de capturas de prueba, en un solo método, que es una señal segura de tiempo para la refactorización.
fuente
He visto este patrón en el código de red, y en realidad tiene sentido. Aquí está la idea básica, en pseudocódigo:
Básicamente es una heurística. Un intento fallido de conectarse podría ser solo un problema de red, pero si ocurre dos veces, eso probablemente significa que la máquina a la que está tratando de conectarse realmente no es accesible. Probablemente hay otras formas de implementar este concepto, pero lo más probable es que sean aún más feas que los intentos anidados.
fuente
Resolví esta situación así (try-catch con fallback):
fuente
He "tenido" que hacer esto en una clase de prueba por coincidencia (JUnit), donde el método setUp () tuvo que crear objetos con parámetros de constructor no válidos en un constructor que arrojó una excepción.
Si tuviera que hacer que fallara la construcción de 3 objetos no válidos, por ejemplo, necesitaría 3 bloques try-catch, anidados. En su lugar, creé un nuevo método, donde se detectaron las excepciones, y el valor de retorno fue una nueva instancia de la clase que estaba probando cuando tuvo éxito.
Por supuesto, solo necesitaba 1 método porque hice lo mismo 3 veces. Puede que no sea una buena solución para bloques anidados que hacen cosas totalmente diferentes, pero al menos su código sería más legible en la mayoría de los casos.
fuente
De hecho, creo que es un antipatrón.
En algunos casos, es posible que desee múltiples capturas de prueba, pero solo si NO SABE qué tipo de error está buscando, por ejemplo:
Si no sabe lo que está buscando, DEBE usar la primera manera, que es IMHO, fea y no funcional. Supongo que este último es mucho mejor.
Entonces, si sabe qué TIPO de error está buscando, sea específico . No es necesario realizar capturas de prueba anidadas o múltiples dentro del mismo método.
fuente
En algunos casos, un Try-Catch anidado es inevitable. Por ejemplo, cuando el código de recuperación de error en sí mismo puede arrojar una excepción. Pero para mejorar la legibilidad del código, siempre puede extraer el bloque anidado en un método propio. Consulte esta publicación de blog para obtener más ejemplos sobre bloques anidados Try-Catch-Finalmente.
fuente
No hay nada mencionado como Anti Pattern en Java en ningún lado. Sí, a pocas cosas llamamos buenas prácticas y malas prácticas.
Si se requiere un bloque try / catch dentro de un bloque catch, no puede evitarlo. Y no hay alternativa. Como un bloque catch no puede funcionar como parte de prueba si se produce una excepción.
Por ejemplo :
Aquí, en el ejemplo anterior, el método arroja una excepción, pero el método doMethod (utilizado para manejar la excepción del método) incluso arroja una excepción. En este caso tenemos que usar el try catch dentro de try catch.
algo que se sugiere no hacer es ...
fuente