Когда написание кода, я нахожу это важным, что мой код хорошо выглядит (кроме того, что это должно работать хорошо). Это хорошо описано в книжном коде, Завершенном (p729): 'Визуальное и интеллектуальное удовольствие хорошо форматировавших код является удовольствием, что немного непрограммистов могут ценить'.
Проблема, как только я получил свой код, функционально работающий, и я начинаю представлять обработку ошибок (попытка - кроме пунктов и т.д.) для создания этого устойчивым, я нахожу, что это обычно портит мой хорошо положенный, кодируют, и превращает его во что-то, что определенно не визуально приятно. Попытка - кроме операторов и дополнительный if's, сделайте код менее читаемым и структурированным.
Интересно, является ли это вызвано тем, что я неправильно использую или злоупотребляю обработку ошибок, или действительно ли это неизбежно? Какие-либо подсказки или приемы для хранения этого красивым?
Трудно дать общий ответ на этот вопрос, поскольку существует множество различных случаев обработки ошибок и, соответственно, множество различных подходов к решению этой проблемы. Если бы вы опубликовали несколько реальных примеров, вы, вероятно, получили бы здесь много предложений по SO, как улучшить ваш код.
В целом, добавление обработки ошибок к существующим функциям делает их больше, поэтому рефакторинг их в более мелкие методы всегда является хорошей идеей. Если вы ищете более общий подход, вам следует освоить Аспектно-ориентированное программирование. Это подход, позволяющий полностью исключить код для так называемых сквозных проблем (например, обработку ошибок) из кода бизнес-логики.
EDIT: Один простой прием:
Я избегаю писать проверки ошибок таким образом:
int MyFunction()
{
if( ErrorCheck1Passes())
{
if( ErrorCheck2Passes())
{
if( ErrorCheck3Passes())
{
callSomeFunction(...);
}
else
return failureCode3;
}
else
return failureCode2;
}
else
return failureCode1;
return 0;
}
Я предпочитаю
int MyFunction()
{
if( !ErrorCheck1Passes())
return failureCode1;
if( !ErrorCheck2Passes())
return failureCode2;
if( !ErrorCheck3Passes())
return failureCode3;
callSomeFunction(...);
return 0;
}
Вы вновь открыли для себя главную причину, по которой Дон Кнут изобрел грамотное программирование: слишком часто обработка ошибок заслоняет основной алгоритм. Если вам повезет, у вас будут некоторые языковые конструкции, которые обеспечат вам некоторую гибкость. Например, исключения могут позволить вам перенести обработку ошибок в другое место, или функции первого класса могут сделать возможным перемещение обработки ошибок и свести проверку if-then-else к вызову функции.
Если вы застряли в языке без этих возможностей, например, в C, вам стоит обратиться к инструментам грамотного программирования. Инструменты грамотного программирования - это препроцессоры, но их задача - помочь вам сделать ваш код более читабельным. У них есть небольшая, но яростная поддержка, и вы сможете найти некоторые рекомендации в Интернете и в опубликованных работах.
Все зависит от того, как вы программируете. Вы можете избежать многих из этих try-catch
(или, как вы выразились, try-except
) операторов, если вы просто выполните правильную проверку ввода. Конечно, это большая работа, чтобы охватить большинство ненужных пользователей, которые пользователи, как правило, помещают в формы и т. Д., Но это сохранит ваши процедуры обработки данных чистыми (или чище ).
Я часто оборачиваю куски кода, требующие обработки ошибок, в собственные функции, которые будут обрабатывать все возможные исключения внутри, и поэтому в некотором смысле всегда будут успешными. Код, который их вызывает, выглядит чище, а если эти функции вызываются более одного раза, то ваш код также становится меньше.
Это может иметь смысл, если вы работаете на переднем крае приложения, где, с точки зрения пользователя, не все возможные исключения должны всплывать на его уровень. В контексте некоторых классов вполне нормально, если существует надежный внутренний способ обработки ошибок и продолжения работы.
Так, например, у меня могут быть функции типа
SaveSettingsSafe();
// 'Safe' in the sense that all errors are handled internally before returning