Я хотел бы добавить сюда, потому что обработка исключений почти во всех кодах java / C #, которые я видел, просто некорректна. То есть в результате вы получаете очень сложную отладочную ошибку для игнорируемых исключений, или, что не менее плохо, вы получаете неясное исключение, которое ничего вам не говорит, потому что слепое следование «отлову (исключение) - это плохо», а все просто хуже.
Во-первых, следует понимать, что исключение - это способ облегчения возврата информации об ошибках между уровнями кода. Теперь ошибка 1: слой - это не просто стековый фрейм, а слой - это код с четко определенной ответственностью. Если вы просто закодировали интерфейсы и подразумеваете это просто потому, что у вас есть более важные вещи, которые нужно исправить.
Если слои хорошо спроектированы и имеют определенные обязанности, то информация об ошибке имеет различное значение, поскольку она всплывает. <-это ключ к тому, что делать, универсального правила не существует. </p>
Итак, это означает, что когда возникает исключение, у вас есть 2 варианта, но вам нужно понять, где в слое вы находитесь:
A) Если вы находитесь в середине уровня, и вы просто внутренняя, обычно частная, вспомогательная функция и что-то идет не так: НЕ БЕСПОКОЙСТВУЙТЕ, пусть вызывающая сторона получит исключение. Это совершенно нормально, потому что у вас нет бизнес-контекста и
1) Вы не игнорируете ошибку и
2) Вызывающий объект является частью вашего слоя и должен был знать, что это может произойти, но теперь вы можете не узнать контекст для его обработки ниже.
или ...
Б) Вы верхняя граница слоя, фасад к внутренностям. Тогда, если вы получите исключение, по умолчанию должно быть CATCH ALL и остановка любых определенных исключений от перехода на верхний уровень, который не будет иметь смысла для вызывающей стороны, или, что еще хуже, вы можете измениться, и вызывающая сторона будет зависеть от реализации деталь и то и другое сломается.
Сила приложения - это уровень развязки между слоями. Здесь вы остановите все как общее правило и сбросите ошибку с общим исключением, переводя информацию в более значимую ошибку для верхнего уровня.
ПРАВИЛО: Все точки входа в слой должны быть защищены CATCH ALL, а все ошибки переведены или обработаны. Теперь это происходит только в 1% случаев, в основном вам просто нужно (или можно) вернуть ошибку в правильной абстракции.
Нет, я уверен, что это очень трудно понять. реальный пример ->
У меня есть пакет, который запускает некоторые симуляции. Эти симуляции в текстовых скриптах. есть пакет, который компилирует эти сценарии, и есть универсальный пакет утилит, который просто читает текстовые файлы и, конечно, базовый java RTL. UML-зависимость ->
Симулятор-> Компилятор-> utilsTextLoader-> Файл Java
1) Если что-то ломается в загрузчике утилит в одном приватном файле, и я получаю FileNotFound, Permissions или что-то еще, просто позвольте этому пройти. Больше ничего не поделаешь.
2) На границе, в первоначально вызванной функции utilsTextLoader вы будете следовать приведенному выше правилу и CATCH_ALL. Компилятору все равно, что произойдет, просто нужно сейчас загрузить файл или нет. Таким образом, в подвохе повторно выведите новое исключение и переведите FileNotFound или что-либо еще в «Не удалось прочитать файл XXXX».
3) Компилятор теперь будет знать, что источник не был загружен. Это ВСЕ, что нужно знать. Поэтому, если я позже изменю utilsTestLoader для загрузки из сети, компилятор не изменится. Если вы отпустите FileNotFound и позже измените его, вы окажете влияние на компилятор даром.
4) Цикл повторяется: фактическая функция, которая вызвала нижний уровень для файла, ничего не сделает при получении исключения. Так что это позволяет ему подняться.
5) Как исключение попадает в слой между симулятором и компилятором, компилятор снова CATCHES_ALL, скрывая любые детали и просто выдает более конкретную ошибку: «Не удалось скомпилировать скрипт XXX»
6) Наконец, повторите цикл еще раз, функция симулятора, которая вызывает компилятор, просто отпускает.
7) Наконец, граница для пользователя. Пользователь это СЛОЙ и все относится. У основного есть попытка, которая делает catches_ALL и, наконец, просто создает красивое диалоговое окно или страницу и «выдает» переведенную ошибку пользователю.
Так видит пользователь.
Симулятор: фатальная ошибка не может запустить симулятор
-Compiler: не удалось скомпилировать скрипт FOO1
- TextLoader: не удалось прочитать файл foo1.scp
--- trl: FileNotFound
Сравнить с:
a) Компилятор: исключение NullPointer <- общий случай и потерянная ночь отладки опечатки имени файла </p>
b) Загрузчик: файл не найден <- Я упоминал, что загрузчик загружает сотни сценариев ?? </p>
или
в) Ничего не происходит, потому что все было проигнорировано !!!
Конечно, это предполагает, что при каждом перебрасывании вы не забыли установить причину исключения.
Ну, мои 2ct. Эти простые правила много раз спасали мою жизнь ...
-Ale