2010-03-15 5 views
8

Я написал класс, который загружает объекты конфигурации моего приложения и отслеживает их, чтобы я мог легко записывать изменения или перезагружать всю конфигурацию сразу одним вызовом метода. Тем не менее, каждый объект конфигурации может потенциально генерировать исключение при выполнении ввода-вывода, но я не хочу, чтобы эти ошибки отменяли общий процесс, чтобы дать другим объектам возможность перезагрузки/записи. Поэтому я собираю все исключения, которые бросаются при повторении объектов и хранят их в супер-исключении, которое бросается после цикла, поскольку каждое исключение все равно нужно обрабатывать, и кто-то должен быть уведомлен о том, что именно пошло не так. Однако этот подход выглядит немного странным для меня. Кто-то там с более чистым решением?Обработка нескольких исключений

Вот код из указанного класса:

public synchronized void store() throws MultipleCauseException 
    { 
    MultipleCauseException me = new MultipleCauseException("unable to store some resources"); 
    for(Resource resource : this.resources.values()) 
     { 
     try 
      { 
      resource.store(); 
      } 
     catch(StoreException e) 
      { 
      me.addCause(e); 
      } 
     } 
    if(me.hasCauses()) 
     throw me; 
    } 

ответ

4

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

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

public interface StoreExceptionHandler { 
    void handle(StoreException exc); 
} 

public synchronized void store(StoreExceptionHandler excHandler) { 
    for (Resource resource : this.resources.values()) { 
     try { 
      resource.store(); 
     } catch (StoreException exc) { 
      excHandler.handle(exc); 
     } 
    } 
    /* ... return normally ... */ 
] 
+0

Учитывая перезагрузку, объекты, которые генерируют исключение, представляют собой последнее возможное согласованное состояние (т. Е. Сохраняют устаревшую копию конфигурации). –

3

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

  • Бросьте исключения необходимости к абстракции (то есть перевод исключение парадигмой)
  • исключения Бросьте рано, если это возможно

То, как вы переводите StoreException к MultipleCauseException себе разумным для меня, хотя сочетание разных типов исключений в один может быть не лучшей идеей. К сожалению, Java не поддерживает общий Throwable s, поэтому, возможно, единственной альтернативой является создание отдельного подкласса MultipleStoreException.

Что касается отбрасывания исключений как можно раньше (что вы НЕ делаете), я скажу, что в определенных случаях можно сгибать правило. Я чувствую, что опасность отсрочки броска - это когда исключительные ситуации излишне связаны с цепной реакцией. Когда это возможно, вы хотите избежать этого и локализовать исключение в максимально возможной области.

В вашем случае, если имеет смысл концептуально подумать о сохранении ресурсов как нескольких независимых задач, тогда может быть «обработать» исключение так, как вы это делали. Однако в других ситуациях, когда задачи имеют более сложную взаимосвязь взаимозависимости, объединение всех этих функций затрудняет задачу анализа исключений.

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

+0

Вы не можете генерировать исключения в Java. –

+0

Ничего себе, это сюрприз. Спасибо что подметил это. – polygenelubricants

+0

Уже пробовал и удивился. Но я не вижу никакой причины, так как дженерики просто расширяются в некоторые неявные отбрасывания, которые были бы действительно полезны здесь.Возможно, кто-то подумал: «У нас есть стирание типа и что-то вроде catch (GenericException e) {} catch (GenericException e) {} не будет работать, поэтому мы не позволяем программистам даже пытаться" –

Смежные вопросы