Якщо мова по суті підтримує винятки, тоді перевагу викидати виключення, і клієнти можуть виловлювати виняток, якщо вони не хочуть, щоб це призвело до помилки. Насправді клієнти вашого коду очікують винятків, і вони зіткнуться з багатьма помилками, оскільки вони не перевірятимуть значення повернення.
Якщо у вас є вибір, ви можете використати винятки.
Повідомлення
Винятки містять повідомлення про помилки, прочитані користувачем, які можуть бути використані розробниками для налагодження або навіть відображатися користувачам при бажанні. Якщо споживчий код не може впоратися з винятком, він завжди може його ввійти, щоб розробники могли пройти журнали, не зупиняючись на будь-якому іншому сліді, щоб з'ясувати, яке було повернене значення, і відобразити його в таблиці, щоб з'ясувати, що було фактичний виняток.
З поверненими значеннями додаткова інформація не може бути легко надана. Деякі мови підтримуватимуть виклики методів для отримання останнього повідомлення про помилку, тому ця проблема загрожує трохи, але це вимагає, щоб абонент здійснював додаткові дзвінки, а іноді потребуватиме доступу до "спеціального об'єкта", який несе цю інформацію.
У випадку повідомлень про виключення я надаю якомога більше контексту, таких як:
Політику імені "foo" не вдалося отримати для користувальницької "бар", на яку посилалось у профілі користувача.
Порівняйте це із зворотним кодом -85. Якому б ви віддали перевагу?
Стеки викликів
Винятки зазвичай також мають детальні стеки викликів, які допомагають швидше та швидше налагоджувати код, і за потреби вони можуть реєструватися кодом виклику. Це дозволяє розробникам чітко визначити проблему в точній лінії, і, таким чином, є дуже потужним. Ще раз порівняйте це з файлом журналу із значеннями, що повертаються (наприклад, -85, 101, 0 тощо), який би ви хотіли?
Невдалий швидко упереджений підхід
Якщо метод називається десь невдалим, він викине виняток. Код виклику повинен або явно придушити виняток, або він не вдасться. Я вважав це насправді дивовижним, оскільки під час розробки та тестування (і навіть у виробництві) код швидко виходить з ладу, змушуючи розробників виправити це. У разі повернення значень, якщо перевірка на повернене значення пропущена, помилка мовчки ігнорується, а помилка повертається десь несподівано, як правило, із значно більшою вартістю налагодження та виправлення.
Обгортка та розгортання винятків
Винятки можуть бути зафіксовані в інших винятках, а потім при необхідності їх розгортати. Наприклад, ваш код може кинути те, ArgumentNullException
що викликовий код міг би загорнутися всередині, UnableToRetrievePolicyException
оскільки ця операція не вдалася в коді виклику. Незважаючи на те, що користувачеві може бути показане повідомлення, подібне до наведеного вище прикладу, деякий діагностичний код може розкрутити виняток і виявити, що ArgumentNullException
причину викликала проблема, що означає, що це код помилки в коді споживача. Тоді це може запустити сповіщення, щоб розробник міг виправити код. Такі розширені сценарії непросто реалізувати із поверненими значеннями.
Простота коду
Це трохи важче пояснити, але я дізнався за допомогою цього кодування як із поверненими значеннями, так і з винятками. Код, написаний за допомогою зворотних значень, зазвичай здійснював дзвінок, а потім проводив ряд перевірок того, що було значенням повернення. У деяких випадках він би викликав інший метод, і тепер буде проведена інша серія перевірок на значення, що повертаються з цього методу. За винятком, обробка винятків набагато простіша у більшості, якщо не у всіх випадках. У вас є блок "try / catch / нарешті", час виконання якого намагається виконати код, нарешті, блокує для очищення. Навіть вкладені блоки try / catch / нарешті порівняно простіше простежити та підтримувати, ніж вкладені if / else та пов'язані з ними значення повернення з декількох методів.
Висновок
Якщо платформа, яку ви використовуєте, підтримує винятки (наприклад, такі як Java або .NET), то вам слід обов'язково припустити, що немає іншого способу, окрім як викидати винятки, оскільки ці платформи мають вказівки щодо викидів винятків, і ваші клієнти збираються очікувати тому. Якщо я використовував вашу бібліотеку, я не буду намагатися перевіряти значення, що повертаються, тому що я очікую, що викиди будуть викинуті, ось такий світ у цих платформах.
Однак, якби це був C ++, визначити його було б складніше, тому що велика база коду вже існує з кодами повернення, і велика кількість розробників налаштована на повернення значень на відміну від винятків (наприклад, Windows насичена HRESULTs) . Крім того, у багатьох додатках це може бути проблемою продуктивності (або, принаймні, сприймається).
try
/catch
існує. Крім того, ви можете поставити вашtry
/catch
набагато далі стек у більш підходяще місце для обробки (що дозволяє розширити проблеми).