вторник, 4 января 2011 г.

21/97: Отделяйте бизнес-исключения от технических

Это перевод Distinguish Business Exceptions from Technical. Автор: Dan Bergh Johnsson.

Из "97-ми вещей, которые должен знать каждый программист".

Есть две причины, почему при выполнении программы возникают ошибки: технические проблемы, которые не дают нам использовать приложение, и бизнес-логика, которая не даёт нам неверно использовать приложение. Большинство современных языков вроде LISP, Java, Smalltalk, Delphi и C# используют исключения для сообщения об обоих классах проблем. Однако эти ситуации настолько различны, что они должны аккуратно быть разделены. Представление их в одной иерархии, не говоря уже про единого предка, является потенциальным источником путаницы.

Неразрешимая техническая проблема может возникнуть, если у вас есть программистская ошибка. К примеру, если вы пытаетесь получить доступ к элементу 83 в массиве с 17 элементами или обратиться к удалённому объекту. В результате у вас будет исключение. Более тонкий пример - вызов библиотечной функции с неверными аргументами.

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

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

Другая, но всё ещё техническая ситуация получится, если программа не может продолжить из-за ошибки в окружении - вроде недоступной БД. В этой ситуации вы должны предположить, что инфраструктура уже сделала всё, что могла для недопущения этой ситуации (повтор соединения несколько раз) - и проиграла. Даже если это не так, то для вызывающего кода ничего не меняется. Он мало что может сделать. Так что мы сигнализируем об этой ситуации аналогичным образом.

В противоположность описанным выше ситуациям, бывает так, что продолжение работы программы невозможно из-за предметно-ориентированной проблемы. В этом случае мы получаем ситуацию, являющуюся исключением, т.е. необычную и нежелаемую, но не вызванную ошибкой в коде программы. Например, если попытаться снять со счета больше денег, чем там есть. Другими словами, эта ситуация – часть бизнес-логики работы, и исключение – лишь альтернативный путь выполнения программы. Такое исключение должно корректно обрабатываться сразу же в точке вызова (или недалеко от неё), непосредственно вызывающей стороной. И для таких ситуаций имеет смысл создать отдельную иерархию исключений.

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

Комментариев нет:

Отправить комментарий

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.