| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Общие вопросы по .NET и C# > throw or not throw |
| Автор: nikitao 8.6.2011, 23:02 | ||||||
| Добрый день. Хочется разобраться в этой теме. Как я понял единства и стандарта в использовании исключений не наблюдается. К примеру Рихтер и Макконнелл 2 ортогональных мнения высказывают в своих книгах ( как мне показалось). Первый говорит - используйте их как можно больше и лучше. Все минусы с лихвой окупятся их плюсами. Второй - "Генерируйте исключения , только в исключительных ситуациях". В Рихтере приводится пример ( пишу по памяти ) : Есть клиент банка , у него есчь счет. Он хочет перевести деньги на другой счет. Пишем :
И дальше метод Transfer должен генирировать исключения , если не достаточно денег на счету , или доступ к одному из аккаунтов запрещен или просто банковская система повисла и т д. Но это все идет в разрез с тем , что говорит Макконнелл( на мой взгляд ) , потому что какие ж это исключительные ситуации - я вполне могу представить , что денег на счету меньше , чем их хотят перевести. Типичная, а не исключительная ситуация... Очень популярна фраза "Генерируйте исключения , только в исключительных ситуациях". И дальше автор приводит какой то травильный пример. Создается впечатление , что понятие исключительная ситуация у программиста впитывается с молоком матери Я серьезно , для меня так самое сложное понять для себя - что такое исключительная ситуация. Просто напросто, если я подумал о какой то ситуации , что она может возникнуть - то она уже не исключительная , раз я ее смог предусмотреть. Бывают случаи , когда действительно понятно , когда надо их генерировать. Там деление на 0 или отсутствие доступа к файлу. Тут понятно, что метод ничего не может поделать, поэтому лучше всего кинуть исключение. Но меня же интересуют совершенно другие ситуации. Приведу пример (уже из моей практики ) Есть какой то класс , которые отправляет сообщения на сервер
Это сообщение может не отправиться с 10 причин : доступ этому аккаунту запрещен , внутренняя ошибка сервера , сервер запросил дополнительную авторизация , сообщение не проходит по каким то фильтрам и т д. Считать это исключительными ситуацией или нет ? Это ошибка - безусловна да. Исключительная ситуация - ну у меня язык не поворачивается это назвать исключительной ситуацией , потому что они возникают чаще , чем не исключительные. (Ну вот там такая специфика работы) Тогда здесь лучше коды возврата использовать ( через енумы ) или как то еще ? Проблема еще в том , что я то пишу библиотеку и я не знаю , как ей будет пользоваться ее пользователь. Как ему будет удобнее ( через енумы или через коды возврата ) Или вот еще пример , где не понятно :
Возвращает -1 , если достигнут конец потока. С чего ? Почему он возвращает -1 , а не генерирует исключение ? По этой логике при делении на 0 - надо возвращать бесконечность или минус бесконечность. Хочется выработать какой то внутренний стандарт относительно этого вопроса. Спасибо. |
| Автор: wester 8.6.2011, 23:45 | ||
| Я думаю что это все зависит от архитектуры проекта в целом. Может архитектура закладывает падать при любой ошибке - например медицинская техника, где при любой ошибке безопаснее выключать аппарат что бы не случилось опасности. для биллинга исключения на мой взгляд лучше не закладывать, а все писать в большой лог. Про деление на ноль. Лично я возвращал бы -1. В своих проектах исключения я просто заменяю на енумы. Удобнее и понятнее.
это все вырабатывается собственным опытом. везде писал "лично" ибо все зависит от архитектуры проекта |
| Автор: nikitao 8.6.2011, 23:55 |
| Ну вот на самом деле хочется как раз узнать кому что их личный опыт подсказывает. wester, я правильно понял , что вы обычно исключения вообще избегаете ? А если в ф-цию передаются неверные параметры ( там null к примеру в кач-ве одного из параметров) вы тоже код возвращаете ? Насчет архитектуры это интересно. Но если предположить , что я пишу библиотеку , то у меня нет всего приложение и значит всей архитектуры в целом. Что тогда делать ? Как считаете ? |
| Автор: ДобренькийПапаша 9.6.2011, 07:30 |
| nikitao, спасибо за тему. Тоже очень хотелось бы узнать мнение более опытных коллег. Особенно в случае, когда архитектура никакая не ясна. С чётким проектированием и разработкой архитектуры начинаются далеко не все проекты и не во всех компаниях |
| Автор: wester 9.6.2011, 15:21 |
| В последнем проекте использовал исключение только в одном случае исключение - если недоступен интернет-ресурс. В этом случае завершалась работа программы, ибо работать в таком случае нельзя. В остальных случаях я возвращал код ошибки через енумы. По поводу передачи некорректного параметра - проверяю параметры на разных уровнях. К примеру у меня реализована работа с БД и заполнением ее данными из инета. Данные которые поступают от пользователя, проверяю на первом уровне и если все данные верны, то вызываю методы (второго уровня) заполнения БД. В противном случае возвращаю код ошибки. Этакий Code Contracts , только со своими плюсами. маленькое обсуждение http://stackoverflow.com/questions/161942/how-slow-are-net-exceptions |
| Автор: mihryak 9.6.2011, 17:34 | ||||
т.е. попробовать списать с клиента деньги за услугу, узнать, что их не хвататет - ну и фиг с ним, потом в логе кто-нибудь заметит, так?
неприемлимо без блокирующей транзакции, т.к. между проверкой и списанием деньги может списать ещё кто-нибудь так что в этом случае - исключение с откатом, и никак иначе! я придерживаюсь следующих принципов для исключений: - неправильные аргументы - недопустимая операция для текущего состояния - несколько несовместимых причин, из-за которых выполнить операцию невозможно (это исключает появление кодов ошибок c-style) - код неспособен как-либо разумно поступить в сложившейся ситуации например, метод List<T>.Remove(T) может вполне себе спокойно вернуть false, если объект не найден но Dictionary<TKey, TValue)[Tkey] не может придумать, что бы ему такого вернуть, если ключ не найден ServiceClient.SendPost() может завалиться по совсем разным причинам, тут исключение, т.к. использовать коды ошибок в .нете не принято |
| Автор: Fieral 9.6.2011, 22:08 |
| Для установки эксепшонов работает простое правило: Выбрасывай исключение только когда больше ничего сделать нельзя. Это автоматически отвечает на вопрос: "Что такое исключительная ситуация?" - это когда больше ничего сделать нельзя. Если можно - разруливай. |