Когда можно использовать обработку исключений для бизнес-логики?

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

try{ _map.put(myKey, myValue); } catch(NullPointerException e){ _map = new HashMap(); } 

Вместо этого ленивая инициализация должна выполняться следующим образом:

 if(_map == null){ _map = new HashMap(); } _map.put(myKey, myValue); 

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

Всякий раз, когда исключение можно ожидать, но не избегать.

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

При правильно спроектированном API это должно сводиться к количеству где-то в диапазоне «практически никогда» до «никогда».

Я не вижу абсолютно никакой причины использовать обработку исключений как средство нормального управления streamом в коде. Это дорого, трудно читать (просто посмотрите на свой собственный первый пример, я понимаю, что он, вероятно, был написан очень быстро, но когда _map не был инициализирован, то, что у вас получается, – это пустая карта, отбрасывающая запись, пытаясь добавить), и он помещает код с бесполезными блоками try-catch, которые могут очень скрыть настоящие проблемы. Опять же, взяв ваш собственный пример, что если вызов _map.add() был вызывать _map.add() NullPointerException по какой-то причине, кроме _map являющейся null ? Внезапно вы тихо воссоздаете пустую карту, а не добавляете в нее запись. Я уверен, что я действительно не могу сказать, может привести к количеству ошибок в совершенно несвязанных местах в коде из-за неожиданного состояния …

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

Выброс исключения – относительно дорогостоящая операция на C ++ и чрезвычайно дорогая в Java. Только по соображениям эффективности никогда не имеет смысла избегать явной проверки и вместо этого принимать исключение. Я полагаю, вы могли бы оправдать его в некоторых редких случаях, когда проверка того, будет ли выбрано исключение, очень сложна или почти невозможна, но в остальном я бы сказал, что ответ «почти никогда».

Это действительно вопрос для обсуждения, и ответ зависит от дизайна вашей системы.

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

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

Во всяком случае, здесь нет единого ответа, вам нужно взвесить оба подхода, а иногда и комбинировать их.

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

Исключение составляют исключения. Существует также причина, по которой разработчики языка Java разбивают все Throwable на два основных типа: проверены и не Throwable .

это хорошая идея полагаться на исключение, происходящее для определенной бизнес-логики?

Да. Абсолютно. Вы должны прочитать главу 9 «Эффективная Java, второе издание». Это все. Красиво объяснили и ждут вас.

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

 try{ // register new user if(getUser(name) != null) throw new MyAppException("Such user already exists"); //other registration steps...... }catch(MyAppException ex){ sendMessage(ex.getMessage()); } 
  • Как определить неиспользуемые определения css
  • Генерировать различные случайные числа в C #
  • Код C ++ в файлах заголовков
  • Когда использовать утверждение и когда использовать исключение
  • Как испускать и выполнять байт-код Java во время выполнения?
  • Отключение автоматического форматирования в Visual Studio
  • Может ли class Java добавлять метод вовремя?
  • Форматирование Литеральные параметры fragmentа кода C #
  • Можете ли вы создавать представления sql / хранимую процедуру с использованием Entity Framework 4.1 Первый подход к коду
  • Как я могу тестировать графический интерфейс?
  • «CompanyName.Foo» - это «пространство имен», но используется как «тип»,
  • Interesting Posts

    Samba против NFS: производительность

    Извлеките все HTML-теги из файла excel

    Удалите Deep Freeze вручную, используя реестр Windows

    Android: Как обнаружить двойное касание?

    Указатель функций, отлитый от другой подписи

    Проверка подлинности зависимостей в автоматизированных системах сборки на основе Maven POM

    Усечение Два десятичных знака без округления

    Любой способ объявить размер / частичную границу поля?

    Как записывать файлы в папку с ресурсами или необработанную папку в Android?

    Будут ли мои приложения и файлы потеряны или МОЖЕТ быть потеряны?

    Как зарядка памяти / фиксации работает в Windows 10?

    Hibernate: где insertable = false, updatable = false принадлежит составным созвездиям первичных ключей с участием внешних ключей?

    Что означает объект ? (JavaScript)

    Как прочитать файл манифеста для webapp, запущенного в apache tomcat?

    Как определить, включено ли «Мобильные сетевые данные» (даже при подключении через WiFi)?

    Давайте будем гением компьютера.