Это антипаттерн? Это приемлемая практика?
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
Мистер смит
источник
источник
Ответы:
Иногда это неизбежно, особенно если ваш код восстановления может выдать исключение.
Не красиво, но иногда нет альтернативы.
источник
Я не думаю, что это антипаттерн, просто широко используется.
Большинство вложенных уловов try действительно избегаемы и ужасны, черт возьми, обычно это продукт младших разработчиков.
Но бывают моменты, когда ты ничего не можешь с этим поделать.
Кроме того, вам понадобится дополнительная инструкция, чтобы обозначить неудачный откат ...
источник
Логика хороша - в некоторых ситуациях может иметь смысл попробовать альтернативный подход, который сам по себе может испытывать исключительные события ... следовательно, эта модель в значительной степени неизбежна.
Однако я бы предложил следующее, чтобы сделать код лучше:
attemptFallbackMethod
иattemptMinimalRecovery
.finally
может ли блок иметь больше смысла - это обычно так для всего, что ощущается как «код очистки ресурса»источник
Все в порядке. Рефакторинг, который нужно рассмотреть, это подтолкнуть код в свой собственный метод и использовать ранние выходы для достижения успеха, позволяя вам писать различные попытки сделать что-то на одном уровне:
После того, как у вас все получится, вы можете подумать о том, чтобы обернуть его в шаблон Стратегии.
Тогда просто используйте
TrySeveralThingsStrategy
, которая является своего рода сложной стратегией (две модели по цене одной!).Одно огромное предостережение: не делайте этого, если ваши стратегии сами по себе не достаточно сложны или вы не хотите использовать их гибкими способами. В противном случае вы получите несколько строк простого кода с огромной кучей ненужной объектной ориентации.
источник
Я не думаю, что это автоматически анти-паттерн, но я бы избежал этого, если бы смог найти более простой и чистый способ сделать то же самое. Если язык программирования, на котором вы работаете, имеет
finally
конструкцию, это может помочь в некоторых случаях это исправить.источник
Не анти-шаблон как таковой, а шаблон кода, который говорит о необходимости рефакторинга.
И это довольно просто, вам просто нужно знать практическое правило, которое записывает не больше, чем блок try в том же методе. Если вы хорошо знаете, как писать связанный код вместе, обычно просто копируете и вставляете каждый блок try с его блоками catch и вставляете его в новый метод, а затем заменяете исходный блок вызовом этого метода.
Это правило основано на предложении Роберта К. Мартина из его книги «Чистый код»:
Быстрый пример на «псевдо-Java». Предположим, у нас есть что-то вроде этого:
Затем мы могли бы реорганизовать каждый try catch, и в этом случае каждый блок try-catch пытается сделать то же самое, но в разных местах (как удобно: D), нам нужно только скопировать вставить один из блоков try-catch и создать метод для него ,
Теперь мы используем это с той же целью, что и раньше.
Надеюсь, это поможет :)
источник
Это, безусловно, снижает читабельность кода. Я сказал бы, если у вас есть шанс , тогда избегайте вложенных попыток ловить.
Если вам нужно вложить пробные уловы, всегда останавливайтесь на минуту и думайте:
у меня есть шанс объединить их?
я должен просто извлечь вложенную часть в новый метод? Код будет намного более чистым.
Это очевидно, если вам нужно вложить три или более уровней try-catch в одном методе, что является верным признаком времени для рефакторинга.
источник
Я видел этот шаблон в сетевом коде, и он действительно имеет смысл. Вот основная идея в псевдокоде:
По сути это эвристика. Одной неудачной попыткой подключения может быть просто сбой сети, но если это происходит дважды, это, вероятно, означает, что машина, к которой вы пытаетесь подключиться, действительно недоступна. Возможно, есть и другие способы реализации этой концепции, но они, скорее всего, будут еще страшнее, чем вложенные попытки.
источник
Я решил эту ситуацию следующим образом (try-catch with fallback):
источник
Я "должен" сделать это в тестовом классе по совпадению (JUnit), где метод setUp () должен был создавать объекты с недопустимыми параметрами конструктора в конструкторе, который вызывал исключение.
Например, если бы мне пришлось сделать сбой при создании 3 недопустимых объектов, мне понадобилось бы 3 блока try-catch, вложенных. Вместо этого я создал новый метод, где исключения были обнаружены, а возвращаемое значение было новым экземпляром класса, который я тестировал, когда это удалось.
Конечно, мне нужен был только 1 метод, потому что я делал то же самое 3 раза. Это может быть не очень хорошим решением для вложенных блоков, которые делают совершенно разные вещи, но, по крайней мере, ваш код станет более читабельным в большинстве случаев.
источник
Я на самом деле думаю, что это антипаттерн.
В некоторых случаях вам может потребоваться несколько попыток, но только если вы НЕ ЗНАЕТЕ, какую ошибку вы ищете, например:
Если вы не знаете, что ищете, вы должны использовать первый способ, который, на мой взгляд, ужасен и не функционален. Я думаю, что последний намного лучше.
Итак, если вы знаете, какой ВИД ошибки вы ищете, будьте конкретны . Нет необходимости во вложенных или нескольких попытках перехвата внутри одного и того же метода.
источник
В некоторых случаях вложенный Try-Catch неизбежен. Например, когда код восстановления ошибки сам может бросить и исключение. Но для улучшения читабельности кода вы всегда можете извлечь вложенный блок в собственный метод. Посмотрите этот пост в блоге, чтобы увидеть больше примеров для вложенных блоков Try-Catch-finally.
источник
Там ничего не упоминается как Anti Pattern в Java нигде. Да, мы называем несколько вещей хорошей практикой и плохой практикой.
Если требуется блок try / catch внутри блока catch, вы не можете помочь. И альтернативы нет. Поскольку блок catch не может работать, попробуйте выполнить часть, если выброшено исключение.
Например :
Здесь в приведенном выше примере метод генерирует исключение, но doMethod (используемый для обработки исключения метода) даже генерирует исключение. В этом случае мы должны использовать try catch внутри try catch.
что-то, что предлагается не делать, это ..
источник