Как следует планировать исключения на архитектурном уровне?

Есть ли хорошие ресурсы для планирования использования исключений с точки зрения архитектуры? (Или предоставьте свои предложения прямо здесь.) В проектах, над которыми я работал, я обнаружил, что несколько общих исключений используются снова и снова и имеют тенденцию терять свое значение. Из: http://jamesjava.blogspot.com/2007/10/exception-plan.html


person James A. N. Stauffer    schedule 17.09.2008    source источник


Ответы (4)


Я наполовину согласен с комментарием Апокалиспа. Экземпляры исключения должны быть зарезервированы для случаев, когда произошла ошибка данных или обработки, но она может быть устранена вмешательством пользователя или системы. Экземпляры RuntimeException должны быть зарезервированы для тех случаев, когда никакое вмешательство в пределах вашего приложения не может решить проблему. Таким образом, эти два типа известны как Checked и Unchecked исключения.

Примером исключений Unchecked может быть, если физический ресурс (такой как база данных или шина сообщений) недоступен. В этом случае RuntimeException хорош, потому что вы не планируете, что ресурс будет недоступен, поэтому вашей бизнес-логике не нужно постоянно проверять наличие DatabaseUnavailableException или что-то подобное. Вы можете обрабатывать RuntimeExceptions по-другому (возможно, AOP отправляет электронное письмо), чтобы сообщить о сбое и позволить персоналу или службе поддержки устранить физическую проблему.

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

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

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

person Spencer Kormos    schedule 23.09.2008
comment
Ваша причина для создания проверенных исключений (плохой ввод данных, неполный доступ к данным, что-то, что не работает с бизнес-логикой) не является исключительными условиями, поэтому исключения не нужны. Таким образом, единственными хорошими исключениями являются непроверенные исключения. - person eljenso; 13.01.2009
comment
Кроме того, я не согласен с recovery=checked; не может восстановить = не отмечено. Вызывающий (или клиентский код) должен поймать и обработать его или нет, и это не должно зависеть от проверенности выброшенного исключения. В большинстве случаев исключения сигнализируют о состояниях, при которых вызывающая сторона не может восстановиться. - person eljenso; 13.01.2009
comment
Вот почему методы должны подавлять исключения и повторно генерировать их как конкретные исключения — если вызывающая сторона не может восстановиться, скажем, из IOException, она должна быть перехвачена внутри и сгенерировано другое исключение, указывающее, что операция не удалась, из которой вызывающая сторона может восстановиться. - person MetroidFan2002; 13.01.2009

Обычно я считаю, что зацикливаться на проверенных исключениях — это излишество. Исключения должны быть зарезервированы для непредвиденных ошибок, после которых программа не может разумно восстановиться. Для них я склонен согласиться с тем, что вы заметили, что специальные типы ошибок имеют тенденцию терять свое значение.

Как правило, генерируется исключение, когда выполняются все следующие условия:

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

Вы обнаружите, что если все это верно, то тип исключения не важен, и вы также можете выдать java.lang.Error. Если какое-либо из них ложно, то исключение, вероятно, является излишним (вам действительно нужны тип, сообщение и трассировка стека?)

Вместо этого рассмотрите возможность увеличения возвращаемого типа методов, чтобы указать ожидаемые виды сбоев. Например, используйте Вариант‹A› type для методов, в которых в некоторых случаях имеет смысл не возвращать значения. Используйте A, B›. type для методов, в которых может потребоваться вернуть значение, тип которого зависит от неудачи или успеха. Там, где раньше у вас могли быть специализированные подтипы исключений, вы можете вместо этого просто использовать «Либо‹Fail,A›», где Fail — это просто перечисление типов ожидаемых сбоев.

person Apocalisp    schedule 17.09.2008
comment
Проголосовали за предложение выдать ошибку, которая никогда не должна выдаваться кодом, не основанным на солнце. Тогда вы никогда не сможете поймать его в стандартном обработчике исключений верхнего уровня, который должен перехватывать Exception. Выброс RuntimeException - гораздо лучшая идея, и его тоже не проверяют. - person MetroidFan2002; 13.01.2009
comment
Да, лучше не делать ничего, что вызвало бы гнев ортодоксальной полиции Явы. Бросьте ошибку на свой страх и риск. Я не могу гарантировать вашу безопасность. - person Apocalisp; 14.01.2009

Я стараюсь, чтобы количество мест, где используется try/finally, значительно превышало количество мест, где используется try/catch. catch обычно зарезервирован для перехвата исключений на верхнем уровне, где их можно разумно обработать, или для обработки исключений из API платформы.

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

person djpowell    schedule 17.09.2008
comment
Это не похоже на архитектурный уровень. :-/ - person James A. N. Stauffer; 18.09.2008

person    schedule
comment
Не могли бы вы опубликовать резюме? - person James A. N. Stauffer; 18.09.2008