Вы чистите, прежде чем делать беспорядок? О размещении кода очистки внутри блока finally - PullRequest
3 голосов
/ 26 ноября 2010

У меня есть вопрос, касающийся обработки исключений и управления ресурсами, и мне было интересно, если кто-нибудь может поделиться своим мнением. Мне нужно выполнить последовательность действий: прочитать настройки приложения, настроить среду, сделать материал и затем в конце концов очистить. Очистка включает разрушение среды, но это должно произойти только в том случае, если она была успешно настроена в первую очередь.

Вот мой первый (и неудачный) подход:

try {
 readSettings();
 setupEnvironment();
} catch (Exception ex) {
 logStackTrace(ex);
 displayError(ex);
 closeCommThreads();
 return;
}

try {
 // do stuff
} catch (Exception ex) {
 logStackTrace(ex);
 displayError(ex);
} finally {
 teardownEnvironment();
 closeCommThreads();
}

Это казалось немного уродливым, поэтому я решил поискать лучшее решение. Я немного читал, и многие статьи голосовали за большие блоки try/catch и использовали (каламбур?) finally для очистки. Итак, вот моя вторая попытка:

try {
 readSettings();
 setupEnvironment();
 // do stuff
} catch (Exception ex) {
 logStackTrace(ex);
 displayError(ex);
} finally {
 teardownEnvironment();
 closeCommThreads();
}

Чтобы сделать эту работу, мне пришлось удалить последовательную связь из teardownEnvironment(), чтобы ее можно было вызывать в любое время - до или после setupEnvironment() (для редакторов: какой-нибудь способ выразить это лучше?). Это правильный подход? Я чувствую себя немного странно, чтобы порвать перед установкой.

Edit:

Просто чтобы сделать это немного более явным: я удалил последовательную связь, добавив дополнительную проверку внутри teardownEnvironment - что-то вроде if (!isSetup()) return;.

Ответы [ 3 ]

2 голосов
/ 26 ноября 2010

Не является правильным или неправильным , если оба способа выполняют то, что вы намереваетесь сделать.

По моему мнению, второй подход (большой блок try / catch / finally) легче читать, поскольку у вас нет оператора возврата, скрытого в блоке catch где-то в теле вашего метода.

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

2 голосов
/ 26 ноября 2010

Подход finally используется для обеспечения гарантии , что перед выбрасыванием исключения используемые ресурсы могут быть закрыты / разыменованы (и готовы для сбора мусора). Это просто для пропаганды исключительной безопасности .

То, что вы только что обсудили здесь, называется Шаблон Dispose . По сути, из-за автоматической природы Java GC вы выполняете очистку ресурсов для среды выполнения.

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

Дополнительная информация: Приобретение ресурсов - это инициализация Может просветить вас?

1 голос
/ 26 ноября 2010

Ну, обычно ваш teardownEnvironment() проверяет

isEnvironmentSetCorrectly() или if(environment != null) или что-либо подобное

, прежде чем вы начнете разрушать.

Так что у вас не будет" чувствовать себя немного странно " по этому поводу, поскольку это не произойдет, если все сделано правильно.

...