Пользовательские исключения: когда мы их используем? Что такое «исключительная» ситуация? - PullRequest
4 голосов
/ 01 ноября 2011

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

В частности, в данный момент я работаю над средством проверки типов для курса по компиляторам. Поэтому у меня есть класс SymbolTable, который довольно похож на Map. Ключевое отличие от вашей обычной картыкаждый символ должен быть определен не более одного раза, поэтому операция put (String, Object) должна завершиться неудачей, если ключ, который мы пытаемся вставить, уже присутствует в SymbolTable.

Так вот вопрос:всякий раз, когда мы пытаемся вставить ключ, и этот ключ уже существует в SymbolTable, как должен вести себя SymbolTable?Должен ли у нас быть метод

boolean insert(String key, Object value);

, который возвращает «ложь» в случае сбоя вставки? Или лучше использовать метод вставки, который имеет возвращаемое значение «void» и выдает исключение, если дублирующее значениесталкивались?

Заранее спасибо:)

Ответы [ 4 ]

2 голосов
/ 01 ноября 2011

Исключения должны быть выброшены на Исключительные случаи .

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

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

Итог, я бы сделал что-то такое:

// Failures can happen 
void add(key, value) throws AlreadyOnMapException

// Update if already on list
void insert(key, value);

// Make available Contains() methods to control the flow by avoiding exceptions
boolean containsKey(key);

boolean containsValue(value);
2 голосов
/ 01 ноября 2011

Решение о том, использовать ли исключение или возвращаемое значение, представляет собой баланс нескольких «сил»:

  • Вызывающий может игнорировать возвращаемое значение и продолжить со следующей строки, но не можетигнорировать исключениеИсключения, как правило, используются в тех случаях, когда игнорирование проблемы и ее продолжение могут привести к более серьезной проблеме.
  • Исключения накладывают бремя на вызывающего, поскольку код для их обработки сложнее, чем просто проверка возвращаемого значения.Поэтому их часто избегают, когда достаточно простого возвращаемого значения.
  • С другой стороны, исключения могут облегчить непосредственный вызов бремени проверки результата, поскольку он может просто доверятьчто если что-то пойдет не так, стек будет разматываться в блок catch где-то еще.
  • Обработка исключений более сложна, чем обычное возвращение, поэтому при частой выдаче происходит сбой в производительности.Исключения обычно используются для ситуаций, которые не должны происходить часто.
  • Когда информация об ошибке и «нормальный» результат относятся к разным типам, выбрасывать исключение обычно лучше, чем вводить несвязанные вещи в один и тот же результат.значение (например, заставить метод возвращать Object, чтобы он мог возвращать либо строку, либо число).

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

0 голосов
/ 01 ноября 2011
User defined exceptions: when do we use them?

Я уверен, что есть очень четко определенные сценарии, где во многих книгах можно использовать пользовательские исключения.Однако недавно я наблюдал интересное использование пользовательских исключений, то есть для улучшения ведения журнала.Например, функция класса A вызывает функцию класса B, а функция класса B вызывает функцию класса C, и все эти функции могут вызывать IO Exception.поэтому, если IO Exception входит в функцию класса C, перехватите это исключение, зарегистрируйте его, теперь создайте объект пользовательского исключения и бросьте этот объект.каждая вызывающая функция будет перехватывать пользовательское исключение наряду с другими исключениями, и всякий раз, когда они отлавливают пользовательское исключение, они НЕ регистрируют его, потому что это будет избыточным, и они просто отбрасывают его назад.

0 голосов
/ 01 ноября 2011

Это действительно зависит от того, что, по вашему мнению, должно произойти. Используя пример вставки, ожидается ли наличие дубликата или это будет ненормально для дубликата? Если ситуация ненормальная (то есть то, что обычно не должно происходить ), то это исключительная ситуация.

Чего не следует делать, так это использовать исключения для управления потоком. Если, скажем, в 10% случаев ожидается наличие дубликата, использование исключения будет неэффективным. Но если со стороны программиста является ошибкой (то есть неожиданным действием) вставить дубликат, когда его не следует вставлять, то, возможно, уместно исключение.

Это уже обсуждалось до смерти, попробуйте немного поискать.

...