Java: как правильно работать с исключениями?

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

Вот примеры: допустим есть метод, который ищет вхождение подстроки в строку. Он должен возвращать индекс вхождения этой самой подстроки в строку. А что нужно возвращать в случае, если метод не нашел искомой подстроки? Может быть генерировать исключение, или возвращать определенное число? Ну тут, думаю, понятно — нужно возвращать "-1".

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

Метод 1: в методе контроллера проверять входящие параметры на допустимое количество карт в колоде.
Метод 2: в классе колоды, в методе сбора колоды из карт и их количества, в случае превышения лимита на карты генерировать исключение, и уже в контроллере затем перехватывать его.

Плюс первого метода в том, исключение не генерируется, нет потери в производительности из за этого. Но есть и минусы — чтобы проверить эти самые лимиты на карты, нужно лезть в базу, вытаскивать оттуда лимиты. А затем, если проверка прошла успешно, при сборе колоды эти действия снова повторяются. Т.е. мы два раза проделываем одну и ту же работу.

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

Какой из способов лучше? И какой совет вы можете дать в общем в таких случаях?
  • Вопрос задан
  • 3713 просмотров
Пригласить эксперта
Ответы на вопрос 5
Я думаю что в вашем случае с картами исключения не нужны. Исключения нужны тогда когда случилась ошибка а не тогда когда чего-то где-то нету!
Приведу пример: у вас есть что-то что работает с базой данных, например какой-то пул. В пуле у вас 10 соединений. Когда закончатся соединения можно кидать исключения. Исключения кидать НУЖНО когда не можете присоединится к БД. Кароче, когда можно написать алгоритм, так чтобы работал нормально, тогда исключение используется только тогда когда возникет «неожиданно» (ожидаемая) ошибка.
Ответ написан
@edelweard
А конкретно по вашей ситуации:
1. На производительность вообще забейте, пока не окажется, что именно в таком-то месте бутылочное горлышко.
2. Общий принцип — не кидать исключение, если ситуация не исключительная.
К примеру, если это в принципе нормально, что карт больше, чем нужно, то кидать исключение не нужно, а нужно обработать эту ситуацию.
А если такого происходить не должно, и всё из-за того, что запрос сформирован неверно, — тогда стоит кидуть IllegalArgumentException.
Ответ написан
@1nd1go
Советую вам обратиться к книге Effective Java (второе издание вроде как свежее).

Исплючениями пользоваться можно и нужно. Думать о перформансе нужно не в первую очередь.

В вашем случае нужно понять, чьей ошибкой является несоответствие в колоде. Если это прям по бизнес-логике кейс, во что верится с трудом, то его стоит обрабатывать обычным кодом, без исключений. Но скорее всего, метод 2 более органичен по своей сути исключительности ситуации.
Ответ написан
Комментировать
YasonBy
@YasonBy
Второй. IllegalArgumentException (или свой наследник) выглядит подходящим вариантом.

В общем случае, следует помнить слова Д.Кнута:
Premature optimization is the root of all evil.
В этом свете единственный плюс первого метода не выглядит сколько-нибудь значимым, и сделать правильный выбор гораздо легче.
Ответ написан
Комментировать
@edelweard
Советую почитать какие-нибудь статьи на эту тему. Это позволит лучше понять механизм исключений и сформулировать для себя некие правила работы с ними.
Например, главу 9 из замечательной книги Effective Java.
Или вот ещё неплохая статья: www.ibm.com/developerworks/java/library/j-jtp05254/index.html
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Bell Integrator Ульяновск
До 400 000 ₽
Bell Integrator Ижевск
До 400 000 ₽
Bell Integrator Хабаровск
До 400 000 ₽
26 июн. 2024, в 16:15
500 руб./за проект
26 июн. 2024, в 16:10
2000 руб./за проект
26 июн. 2024, в 15:48
30000 руб./за проект