Обработка ошибок внутри или вне класса? - PullRequest
0 голосов
/ 28 ноября 2009

Обычно я делаю все, что могу внутри класса, в каждом method (try и catch). Я делаю это неправильно? Недавно я слышал, что лучше обрабатывать ошибки в теле программы ...

Что такое хорошая привычка?

Ответы [ 6 ]

7 голосов
/ 28 ноября 2009

Если вы можете обработать исключение, сделайте это. Если вы не можете, то пусть исключение всплывет перед тем, кто может!

4 голосов
/ 28 ноября 2009

Некоторые общие мысли:

  1. Бросать исключения только для исключительных состояний ошибки.

  2. Сбой быстро.

  3. Поскольку вы генерируете исключения только для исключительных состояний ошибки, предполагается, что вы не можете исправить это в классе, поэтому исключение должно пузыриться в стеке вызовов. Обрабатываете ли вы это в ближайшем классе над ним, или обрабатываете его в ловушке, - решать только вам.

2 голосов
/ 16 апреля 2010

То, как вы взаимодействуете с исключениями, зависит от того, где ваш код находится в слоях приложения. В общем, отчеты об ошибках - это вопрос пользовательского интерфейса, и обычно их лучше оставить приложению, самому внешнему слою кода.

Код низкого уровня и код бизнес-логики среднего уровня часто используются разными приложениями. Поскольку разные приложения будут иметь разные политики относительно того, сколько и какие ошибки следует сообщать пользователю, код низкого и среднего уровня должен избегать обработки исключений с целью сообщения об ошибках. Пусть приложение сделает это.

Существует множество законных причин для захвата исключения в низкоуровневом и среднем уровне кода, в частности, чтобы попробовать альтернативный путь в случае сбоя основного пути, или преобразовать низкоуровневое исключение в исключение, более специфичное для текущая операция. Просто будьте осторожны, чтобы не переборщить, сделайте ваши исключения ловушками как можно более конкретными (не чрезмерно обобщайте, или вы будете ловить вещи, с которыми вы не готовы справиться), и будьте крайне критичны к подавлению исключения полностью на низком и среднем уровне. код.

Общая философия для кода низкого и среднего уровня должна заключаться в следующем: если действие, запрошенное вызывающим абонентом, не выполняется, то пусть вызывающий абонент увидит последствия - исключение.

Ваш код низкого и среднего уровня часто попадает в два лагеря: «сложные» функции, которые либо выполняют запрошенное действие, либо выдают исключение, если это невозможно, и «мягкие» функции, которые более удобны для экспериментального исследования. Если операция, вероятно, в большинстве случаев завершится с ошибкой, например, FileExists (), то, вероятно, использование исключений будет плохим, чтобы вызвать исключение при сбое и потребовать, чтобы вызывающий объект обернул все вызовы этой функции в обработчике исключений. Это создало бы больше работы для звонящего. В этом случае FileExists () должна быть «мягкой» функцией, которая возвращает true / false вместо броска. «Жесткая» версия этого может называться «RequireFile ()», который выдает, если файл не найден.

В качестве шаблона именования вы часто видите «Try» в качестве префикса к программным функциям. Таким образом, GetData () была бы сложной функцией, которая генерирует, если она не может выполнить работу, а TryGetData () была бы мягкой функцией, которая возвращает логическое значение вместо броска. В зависимости от использования, часто можно увидеть обе функции в классе или библиотеке.

Эти пары часто реализуются как одна, вызывающая другую - GetData () вызывает TryGetData () и выдает, если TryGetData () возвращает false, или TryGetData () вызывает GetData () внутри блока try..catch. Какой шаблон использовать, зависит от сложности работы, выполняемой функцией. Если случай сбоя легко обнаруживается с помощью логической логики (низкий риск исключений), тогда TryGetData будет основной реализацией. Если в случае сбоя происходит сбой по исключению, то GetData будет основной реализацией.

«Жесткие» функции позволяют вызывающему использовать все преимущества исключений для упрощения логики программы - если этот вызов завершится успешно, я могу перейти к следующему шагу, используя результаты вызова. Если этот вызов не удастся, он выдаст исключение и следующий шаг не будет выполнен. «Жесткие» функции позволяют выполнять последовательность операций с правильным допущением, что каждая операция возвращает законные результаты, потому что, если операция не может вернуть законные результаты, она выбрасывает нас из этой последовательности операций. Это позволяет вам сконцентрировать логику программы первичного пути без помех обработки ошибок пожарной бригады - анализируя коды ошибок функций при каждом вызове и решая, что с ними делать.

2 голосов
/ 29 ноября 2009

Как правило, обработка исключений должна выполняться в логике / уровне бизнес / контроллеров всякий раз, когда вам нужно «перевести» исключение конечному пользователю. Так, например, не в уровне данных, уровне модели, уровне представления и служебных классах.

Отлов исключений времени выполнения, таких как нулевые указатели, арифметические ошибки, индекс массива за пределами границ и т. Д., Как правило, не должен выполняться. В целом они просто указывают на ошибки при программировании. Вы должны просто написать соответствующий код, чтобы они никогда не возникали (например, if (x != null) { x.doStuff() }).

0 голосов
/ 28 ноября 2009

Я считаю, что лучшим подходом может быть смешанный подход.

Выполнение обработки ошибок в классе для проблем, относящихся к классу. Например, если установщики свойств выполняют проверку, эти ошибки обнаруживаются и выбрасываются из класса.

На уровне веб-страницы или формы вы можете обработать все ошибки одним способом. Например, для веб-приложения ASP.Net вы можете использовать метод Page_Error, чтобы перехватывать все исключения, которые достигают страницы. Затем вы отображаете текст сообщения об ошибке, выданный установщиком свойства класса.

Кроме того, вы можете включить возвращаемое значение строки errorMessage в каждую сигнатуру метода. Вызывающая страница / форма проверяет содержимое errorMessage и решает, что делать в зависимости от контекста. Это требует больше кодирования, чем описанный выше подход.

Иногда класс не знает, действительно ли событие является ошибкой. Например, если метод класса выбирает запись из базы данных и возвращает ее данные, класс не знает, является ли это ошибкой. Если страница / форма, вызывающая метод класса, является страницей поиска, то получение не возвращенных записей не является ошибкой, это «запись не найдена», и эта информация отображается.

0 голосов
/ 28 ноября 2009

Вы должны обрабатывать исключения всякий раз, когда можете произвести продуктивную реакцию. Если он должен подниматься выше, то пусть.

Я также переупаковываю исключения, как только они могут быть сгенерированы некоторым слоем ниже моего кода. Хороший пример преимущества можно увидеть в выполнении вызовов SQL в Java. Все выдает SQLException, что бесполезно, если у меня есть метод, который может вызвать множественные исключения, но не может их обработать. Переупаковывая, я могу различать и по-разному реагировать между неудачным соединением и проблемой построения подготовленного оператора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...