мне давно не дает покоя чувство неполноценности читая свой код (C++), я давно ловлю себя на мысли что обработка исключений в моем коде не красива, а часто вычурна и ужасна. Конечно все работает, но эстетической привлекательности у такого кода — 0.
Так вот, после продолжительных сеансов медитации и самоанализа , я так и не смог придумать сколько нибудь внятной стратегии обрабоки исключений .
Может быть кто-нибудь поделиться документиком или просто мыслями на данную тему...
Игорь
20.03.03 13:21: Перенесено модератором из '.NET' — TK
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Здравствуйте, joker6413, Вы писали:
ВВ>Ты бы это, примерчик привел. А то непонятно что конкретно там у тебя не соответствует требованиям "эстетики".
ВВ>Зы. А вообще, как говорил Глючный Мастдай, не нужно менять то, что и так работает.
Это конечно не самый большой кусок...
проблема в том что обработку exception приходиться делать на нескольких уровнях вложенности, а в следствие постепенного изменения кода (результат изменения требований) такие обработчики становяться не нужными, или наоборот надо создавать новые обработчики. Сам видишь сколько это требует кода... В функции ProcessBaseException и ProcessCException уже вынесена соотв обработка.
[...skipped...]
J>Это конечно не самый большой кусок... J>проблема в том что обработку exception приходиться делать на нескольких уровнях вложенности, а в следствие постепенного изменения кода (результат изменения требований) такие обработчики становяться не нужными, или наоборот надо создавать новые обработчики. Сам видишь сколько это требует кода... В функции ProcessBaseException и ProcessCException уже вынесена соотв обработка.
Я пользуюсь таким общим правилом — ставить обработку исключений только на самом высоком уровне вызовов, т.е. в обработчиках событий, в точках входа в поток и т.д. В этим местах вызывается общая функция, которая показывает сообщение об ошибке, заносит в лог файл или делает что-либо другое, подходящее в данной ситуации.
Исключение составляют случаи, когда системное исключение нужно конвертировать в пользователе-ориентированное, тогда обработка идет в месте вызова системной функции.
J>мне давно не дает покоя чувство неполноценности читая свой код (C++), я давно ловлю себя на мысли что обработка исключений в моем коде не красива, а часто вычурна и ужасна.
. J>Может быть кто-нибудь поделиться документиком или просто мыслями на данную тему...
Моё мнение — обрабатывать исключения нужно пореже. Разве что вот таким образом:
void CompleteMcLaud()
{
try
{
KillTheFile();
}
catch( Exception e )
{
throw new Exception("File was not gone.",e);
}
}
Тут мне на эту тему ещё вот что прислали: "И вообще, надо больше работать с глючными программами. Глюков это не исправит, зато заработаете больше денег."
J>мне давно не дает покоя чувство неполноценности читая свой код (C++), я давно ловлю себя на мысли что обработка исключений в моем коде не красива, а часто вычурна и ужасна.
. J>Может быть кто-нибудь поделиться документиком или просто мыслями на данную тему...
Моё мнение — обрабатывать исключения нужно пореже. Разве что вот таким образом:
void CompleteMcLaud()
{
try
{
KillTheFile();
}
catch( Exception e )
{
throw new Exception("File was not gone.",e);
}
}
Тут мне на эту тему ещё вот что прислали: "И вообще, надо больше работать с глючными программами. Глюков это не исправит, зато заработаете больше денег."
Просто исполнение будет стопориться на первом же эксепшине. Зачем дальнейшая обработка?
J>проблема в том что обработку exception приходиться делать на нескольких уровнях вложенности
Зачем?
J>а в следствие постепенного изменения кода (результат изменения требований) такие обработчики становяться не нужными, или наоборот надо создавать новые обработчики.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Здравствуйте, joker6413, Вы писали:
ВВ>Само собой, недостаточно контекстной информации и все такое, но по идее процедурка ведь простая, так не лучше ли -
ВВ>
ВВ>Просто исполнение будет стопориться на первом же эксепшине. Зачем дальнейшая обработка?
J>>проблема в том что обработку exception приходиться делать на нескольких уровнях вложенности
ВВ>Зачем?
Потому что мне надо было обрабатывать MFC исключения (CException) и мои исключения(CBaseException) (ну вот так архитектурно сложилось...). Хуже того pUManager объект довольно навороченного класса, он используется во многих местах и надо было знать каким путем шла раскрутка исключений...
J>>а в следствие постепенного изменения кода (результат изменения требований) такие обработчики становяться не нужными, или наоборот надо создавать новые обработчики.
ВВ>А это уже ХР. С ним легко не бывает.
Обработка исключения, вообще, в нынешних языках очень ужасна и не удобна. Вернее, я бы сказал так, нынешние языки предоставляют очень мало языковых конструкций для обработки исключений.
1. Нельзя, например, повторно заюзать код обрабатывающий исключения
2. Некрасиво реализуется конструкция: перебери варианты по очереди и заюзай первый из неотказавших.
3. Также некрасиво реализуется конструкция: продолжай выполнение даже, если часть кода отказала.
т.е. в нынешних языках, вообще, нет ни каких-то логический, структурных и т.д. средств для работы с исключениями.
ИМХО, это связано с тем, что исключения достаточно молодая технология, которая еще достаточно не обкатана.
Здравствуйте, DarkGray, Вы писали:
DG>т.е. в нынешних языках, вообще, нет ни каких-то логический, структурных и т.д. средств для работы с исключениями.
Согласен. Мне не нравится и то, что даже в новых технология это не решается. Например, аспектно-ориентированный подход довольно естественно мог бы решить эту проблему, однако увы...
Здравствуйте, DarkGray, Вы писали:
DG>Здравствуйте, joker6413, Вы писали:
DG>Обработка исключения, вообще, в нынешних языках очень ужасна и не удобна. Вернее, я бы сказал так, нынешние языки предоставляют очень мало языковых конструкций для обработки исключений.
DG>1. Нельзя, например, повторно заюзать код обрабатывающий исключения
В языках с поддержкой closures — елементарно (Smalltalk, CLOS, ...)
DG>2. Некрасиво реализуется конструкция: перебери варианты по очереди и заюзай первый из неотказавших.
Аналогично.
DG>3. Также некрасиво реализуется конструкция: продолжай выполнение даже, если часть кода отказала.
Аналогично.
DG>т.е. в нынешних языках, вообще, нет ни каких-то логический, структурных и т.д. средств для работы с исключениями.
DG>ИМХО, это связано с тем, что исключения достаточно молодая технология, которая еще достаточно не обкатана.
DG>
Если все это для тебя критично, то use the right tool.
Здравствуйте, _vovin, Вы писали:
DG>>Обработка исключения, вообще, в нынешних языках очень ужасна и не удобна. Вернее, я бы сказал так, нынешние языки предоставляют очень мало языковых конструкций для обработки исключений.
DG>>1. Нельзя, например, повторно заюзать код обрабатывающий исключения
V>В языках с поддержкой closures — елементарно (Smalltalk, CLOS, ...)
А покажите, пожалуйста, как решаются эти три проблемы с использованием closures.
V>Если все это для тебя критично, то use the right tool.
Не то, чтобы критично, но то, что неудобно/неприятно — это факт.
Здравствуйте, _vovin, Вы писали:
V>Здравствуйте, DarkGray, Вы писали:
DG>>Здравствуйте, joker6413, Вы писали:
DG>>Обработка исключения, вообще, в нынешних языках очень ужасна и не удобна. Вернее, я бы сказал так, нынешние языки предоставляют очень мало языковых конструкций для обработки исключений.
DG>>1. Нельзя, например, повторно заюзать код обрабатывающий исключения
V>В языках с поддержкой closures — елементарно (Smalltalk, CLOS, ...)
Не понял , closures что за волшебная конструкция которой нет в c++?
DG>>2. Некрасиво реализуется конструкция: перебери варианты по очереди и заюзай первый из неотказавших.
V>Аналогично.
DG>>3. Также некрасиво реализуется конструкция: продолжай выполнение даже, если часть кода отказала.
V>Аналогично.
DG>>т.е. в нынешних языках, вообще, нет ни каких-то логический, структурных и т.д. средств для работы с исключениями.
DG>>ИМХО, это связано с тем, что исключения достаточно молодая технология, которая еще достаточно не обкатана.
DG>>
V>Если все это для тебя критично, то use the right tool.
V>--
V>Владимир.
Здравствуйте, DarkGray, Вы писали:
DG>Здравствуйте, _vovin, Вы писали:
DG>>>Обработка исключения, вообще, в нынешних языках очень ужасна и не удобна. Вернее, я бы сказал так, нынешние языки предоставляют очень мало языковых конструкций для обработки исключений.
DG>>>1. Нельзя, например, повторно заюзать код обрабатывающий исключения
V>>В языках с поддержкой closures — елементарно (Smalltalk, CLOS, ...)
DG>А покажите, пожалуйста, как решаются эти три проблемы с использованием closures.
Извини, если код для тебя не будет читаться, это ведь Smalltalk.
[...skipped...]
J>Не понял , closures что за волшебная конструкция которой нет в c++?
В C++ нет многих "волшебных" конструкций.
Грубо говоря, это кусочек кода внутри метода, выполнение которого отложено до момента, когда ты сам решишь это сделать. Его ты можешь передавать как объект куда угодно, при этом он "замыкает" (отсюда и название — closure — замыкание) на себя контекст метода в момент создания.
Спасибо.
V>Извини, если код для тебя не будет читаться, это ведь Smalltalk.
Еще бы вольный перевод на C-ишный-синтаксис а то я о SmallTalk-е знаю только основные концепции
V>2. Нельзя ли поточнее сформулировать, чтобы можно было привести пример?
Абстрактно:
Пытаемся получить настройки из удаленной базы
если ошибка, то
получаем настройки из локальной базы,
если ошибка, то
получаем настройки из файла,
если ошибка, то
берем default-ные настройки
иначе
генерим исключение, которое включает в себя, все эти 4 исключения
Здравствуйте, _vovin, Вы писали:
V>Здравствуйте, DarkGray, Вы писали:
DG>>Здравствуйте, _vovin, Вы писали:
DG>>>>Обработка исключения, вообще, в нынешних языках очень ужасна и не удобна. Вернее, я бы сказал так, нынешние языки предоставляют очень мало языковых конструкций для обработки исключений.
DG>>>>1. Нельзя, например, повторно заюзать код обрабатывающий исключения
V>>>В языках с поддержкой closures — елементарно (Smalltalk, CLOS, ...)
DG>>А покажите, пожалуйста, как решаются эти три проблемы с использованием closures.
V>Извини, если код для тебя не будет читаться, это ведь Smalltalk.
V>1. Универсальный обработчик
V>
Нет так не интересно, конечно я тоже могу написать функцию которая принимает указатель на базовый тип всех моих исключений, узнавать их "настоящий" тип и что то делать... НО! при обработке ислючений важен КОНТЕКСТ выполнения (какие локальные объекты уже созданы, какие методы уже вызваны и т.д.) неужели в каком-то языке можно попользовать контекст выполнения "удаленно"
V>2. Нельзя ли поточнее сформулировать, чтобы можно было привести пример?
V>3. Продолжать выполнение не глядя на исключение.
V>
V>[self someNastyAction] on: Exception do: [:ex | ex resume]
V>
V>>>Если все это для тебя критично, то use the right tool.
DG>>Не то, чтобы критично, но то, что неудобно/неприятно — это факт.
V>Есть надежда, что гиганты когда-нибудь перестанут гоняться за голой скоростью, чтобы не приходилось вдвое больше ненужного кода писать.
V>--
V>Владимир.
Здравствуйте, DarkGray, Вы писали:
DG>Здравствуйте, _vovin, Вы писали:
DG>Спасибо.
V>>Извини, если код для тебя не будет читаться, это ведь Smalltalk.
DG>Еще бы вольный перевод на C-ишный-синтаксис а то я о SmallTalk-е знаю только основные концепции
Ну, представь, что try-catch это обычная функция, в которую передаются блоки кода (анонимные функции). Т.е. ты можешь создавать собственные ф-ции вида try-catch с любым кодом.
С таким дизайном уже можно придумать решение твоих задач?
V>>2. Нельзя ли поточнее сформулировать, чтобы можно было привести пример?
DG>Абстрактно: DG> Пытаемся получить настройки из удаленной базы DG>если ошибка, то DG> получаем настройки из локальной базы, DG>если ошибка, то DG> получаем настройки из файла, DG>если ошибка, то DG> берем default-ные настройки DG>иначе DG> генерим исключение, которое включает в себя, все эти 4 исключения
Формируем последовательность из closures с этими действиями, потом в цикле выполняем, если завершилось успешно, то выйти из цикла.
Т.е. использование будет выглядет примерно так:
self performSuccessful:
(Array
with: [ " из базы " ]
with: [ " из локальной базы " ]
with: [ " из файла " ])
Здравствуйте, joker6413, Вы писали:
J>Нет так не интересно, конечно я тоже могу написать функцию которая принимает указатель на базовый тип всех моих исключений, узнавать их "настоящий" тип и что то делать... НО! при обработке ислючений важен КОНТЕКСТ выполнения (какие локальные объекты уже созданы, какие методы уже вызваны и т.д.) неужели в каком-то языке можно попользовать контекст выполнения "удаленно"
Один универсальный обработчик на все случаи жизни и для любых проектов?
Что значит "удаленно" и какую конкретную задачу нужно решить?
Здравствуйте, _vovin, Вы писали:
V>Ну, представь, что try-catch это обычная функция, в которую передаются блоки кода (анонимные функции). Т.е. ты можешь создавать собственные ф-ции вида try-catch с любым кодом.