Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Инициируйте исключения, соответствующие абстракции



 

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

Во избежание этой проблемы верхние уровни приложения должны пере­хватывать исключения нижних уровней и, в свою очередь, инициировать ис­ключения, которые можно объяснить в терминах абстракции верхнего уровня. Описываемая идиома, которую мы называем трансляцией исключении. (exception translation), выглядит следующим образом:

 

// Трансляция исключения

try {

// Использование абстракции нижнего уровня

// для выполнения наших указаний

} catch(LowerLevelException е) {

throw new HigherLevelException( ... ); }

 

167

 

Приведем конкретный пример трансляции исключения, взятый из класса AbstractSequentialList, который представляет собой скелетную реализацию (статья 16) интерфейса List. В этом примере трансляция исключения продиктована спецификацией метода get в интерфейсе List:

 

/**

* Возвращает элемент, находящийся в указанной позиции

* в заданном списке.

* @throws IndexOutOfBoundsException, если индекс находится

* за пределами диапазона (index < 0 II index >= size()).

*/

public Object get(int index) {

           ListIterator i = listItеrаtor(index);                       

try {

return i. next();

catch (NoSuchElementException е) {

throw new IndexOutOfBoundsException("Index: " + index); }

}

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

 

// Сцепление исключений

try {

// Использование абстракции нижнего уровня

// для выполнения наших указаний

} catch(LowerLevelException е) {

throw new H1gherLevelException(e); }

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

 

// Сцепление исключений в версии 1.4

HigherLevelException(Throwable t) {

super(t);   }

 

 

168

 

Если же вы используете более раннюю версию, ваше исключение должно само сохранять исключение нижнего уровня и предоставлять соответствующий метод доступа:

// Сцепление исключений в версии, предшествующей 1.4

private Throwable cause;

НighегLеvеlЕхсерtiоп(Тhгоwаblе t) {

cause = t; }

public Throwable getCause() {

return cause; }

Дав методу доступа название getCause и применив указанную декларацию, вы получите гарантию того, что ваше исключение будет взаимодействовать с механизмом сцепления исключений для данной платформы так, как если бы вы использовали иск­лючение в версии 1.4. Это дает то преимущество, что в исключение верхнего уровня стандартным образом будет интегрирована трассировка стека для исключения нижнего уровня. Кроме того, это позволяет задействовать стандартные средства отладки для доступа к исключению нижнего уровня.

Хотя трансляция исключений лучше, чем бессмысленная передача исклю­чений с нижних уровней, злоупотреблять ею не следует. Самый хороши" способ обработки исключений нижнего уровня - полностью исключить их возможность. Для этого перед выбором метода нижнего уровня необходимо убедиться в том, что он будет выполнен успешно, иногда добиться этого можно путем явной проверки аргументов метода верхнего уровня перед их передачей на нижний уровень.

Если предупредить появление исключений на нижних уровнях невозможно, то лучшее решение состоит в том, чтобы верхний уровень молча обрабатывал эти исключения, изолируя клиента от проблем нижнего уровня. В таких условиях чаще всего достаточно протоколировать исключения, используя какой-либо механизм регистра­ции, например java,util,logging, появившийся в версии 1.4. Это дает возможность администратору исследовать возникшую проблему и в то же время изолирует от нее программный код клиента и конечного пользователя.

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

 

169

 


Поделиться:



Последнее изменение этой страницы: 2019-04-11; Просмотров: 226; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.014 с.)
Главная | Случайная страница | Обратная связь