Сейчас тема по работе с исключениями является холиварной. Программисты делятся на тех, кто против исключений, считая что их генерация является слишком дорогой операцией, и пользоваться ими надо только в самых крайних случаях, когда другого пути нет. Другие считают, что это очень удобный инструмент, и не пользоваться им — глупо. Я пока не примкнул ни к тому, ни к другому лагерю. Хочу выслушать разные мнения, и, возможно, сделать для себя выводы.
Вот примеры: допустим есть метод, который ищет вхождение подстроки в строку. Он должен возвращать индекс вхождения этой самой подстроки в строку. А что нужно возвращать в случае, если метод не нашел искомой подстроки? Может быть генерировать исключение, или возвращать определенное число? Ну тут, думаю, понятно — нужно возвращать "-1".
Но есть и примеры посложнее. Вот мой сегодняшний пример из работы: пишется карточная игра. Есть метод контроллера, который должен из пришедших параметров собрать колоду. В параметрах соответственно есть карты и их количество. Внутри себя этот метод делегирует другому классу(классу колоды) сбор колоды из указанных карт и их количества. Суть в том, что в колоде не может быть карт каждого типа больше определенного количества. Вопрос в следующем: как лучше поступить?
Метод 1: в методе контроллера проверять входящие параметры на допустимое количество карт в колоде.
Метод 2: в классе колоды, в методе сбора колоды из карт и их количества, в случае превышения лимита на карты генерировать исключение, и уже в контроллере затем перехватывать его.
Плюс первого метода в том, исключение не генерируется, нет потери в производительности из за этого. Но есть и минусы — чтобы проверить эти самые лимиты на карты, нужно лезть в базу, вытаскивать оттуда лимиты. А затем, если проверка прошла успешно, при сборе колоды эти действия снова повторяются. Т.е. мы два раза проделываем одну и ту же работу.
Во втором же методе все в одном месте: и логично, и проверка проходит в то же время, когда карты вытаскиваются из базы данных — не нужно лезть туда по нескольку раз.
Какой из способов лучше? И какой совет вы можете дать в общем в таких случаях?
Я думаю что в вашем случае с картами исключения не нужны. Исключения нужны тогда когда случилась ошибка а не тогда когда чего-то где-то нету!
Приведу пример: у вас есть что-то что работает с базой данных, например какой-то пул. В пуле у вас 10 соединений. Когда закончатся соединения можно кидать исключения. Исключения кидать НУЖНО когда не можете присоединится к БД. Кароче, когда можно написать алгоритм, так чтобы работал нормально, тогда исключение используется только тогда когда возникет «неожиданно» (ожидаемая) ошибка.
А конкретно по вашей ситуации:
1. На производительность вообще забейте, пока не окажется, что именно в таком-то месте бутылочное горлышко.
2. Общий принцип — не кидать исключение, если ситуация не исключительная.
К примеру, если это в принципе нормально, что карт больше, чем нужно, то кидать исключение не нужно, а нужно обработать эту ситуацию.
А если такого происходить не должно, и всё из-за того, что запрос сформирован неверно, — тогда стоит кидуть IllegalArgumentException.
В принципе, на стороне клиента должна быть базовая проверка того, что игрок пытается запихать больше чем нужно карт. Поэтому на сервер могут придти неверные параметры только в случае, если игрок сам попытается «подделать» запрос. По этой логике получается, что это исключительная ситуация.
Если на стороне клиента выполняются все проверки, то на сервере вообще можно исключить подробную обработку таких кейзов. Шаг в лево, шаг в право — логирование и 400 Bad request в ответ. Ибо зачем тратить время процессорное время на кулхацкеров.
Советую вам обратиться к книге Effective Java (второе издание вроде как свежее).
Исплючениями пользоваться можно и нужно. Думать о перформансе нужно не в первую очередь.
В вашем случае нужно понять, чьей ошибкой является несоответствие в колоде. Если это прям по бизнес-логике кейс, во что верится с трудом, то его стоит обрабатывать обычным кодом, без исключений. Но скорее всего, метод 2 более органичен по своей сути исключительности ситуации.
Спасибо за грамотную(это значит отличная, раньше в СССР за хорошие вещи давали почтную грамоту) ссылку. На эту статью есть перевод на расово-верном языке