Использовать продолжение или проверку Исключения при проверке и обработке объектов


3

Я обрабатываю, скажем, список объектов «Документ». Прежде чем записать обработку документа успешно, я сначала хочу проверить пару вещей. Скажем, файл, относящийся к документу, должен присутствовать и что-то в документе должно присутствовать. Просто две простые проверки для примера, но запомните еще 8 проверок, прежде чем я успешно обработаю свой документ.

Что бы вы хотели?

for (Document document : List<Document> documents) { 
    if (!fileIsPresent(document)) { 
     doSomethingWithThisResult("File is not present"); 
     continue; 
    } 
    if (!isSomethingInTheDocumentPresent(document)) { 
     doSomethingWithThisResult("Something is not in the document"); 
     continue; 
    } 
    doSomethingWithTheSucces(); 
} 

Или

for (Document document : List<Document> documents) { 
    try { 
     fileIsPresent(document); 
     isSomethingInTheDocumentPresent(document); 
     doSomethingWithTheSucces(); 
    } catch (ProcessingException e) { 
     doSomethingWithTheExceptionalCase(e.getMessage()); 
    } 
} 

public boolean fileIsPresent(Document document) throws ProcessingException { 
    ... throw new ProcessingException("File is not present"); 
}  

public boolean isSomethingInTheDocumentPresent(Document document) throws ProcessingException { 
    ... throw new ProcessingException("Something is not in the document"); 
} 

Что более читаемым. Что лучше? Есть ли даже лучший способ сделать это (возможно, используя какой-то шаблон дизайна)?

Насколько читаемость идет мои предпочтения в настоящее время является вариант Exception ...

Что твое?

4

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

for (Document document : List<Document> documents) { 
    if(checkDocument(document)) { 
     doSomethingWithTheSucces(); 
    } else { 
     doSomethingWithTheError(); 
    } 
} 

// Later: 
public boolean checkDocument(Document doc) { ... } 

Если вам не нужно знать, почему он не тогда ваш checkDocument() может просто возвращать логическое значение и, возможно, войти, в чем проблема. Если ваш код должен знать, в чем проблема, то что-то вроде этого:

for (Document document : List<Document> documents) { 
    try { 
     checkDocument(document); 
     doSomethingWithTheSucces(); 
    } catch(CheckDocumentException ex) { 
     doSomethingWithTheError(ex); 
    } 
} 

// Later: 
public void checkDocument(Document doc) throws CheckDocumentException { ... } 

Вы также можете иметь checkDocument() возвращает какое-то коды возврата, а не исключение, но я думаю, что исключение лучше для обработки сложные данные об ошибках.

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

  0

Возможно, даже если (document.isValid()) ... Ницца! Спасибо за твист в размышлении об этом ... 23 сен. 082008-09-23 20:56:59

  0

Документ действителен выглядит более oop. Возможно, вы могли бы просто поместить весь этот код внутри класса Document. 24 сен. 082008-09-24 03:40:27

  0

Я был (возможно, неправильно), предполагая, что класс Document был запечатан или встроенный класс, а не пользовательский. Кроме того, запись метода isValid() в Document будет работать только в том случае, если Document знает, что может быть действительным и что не может. В зависимости от того, что делает проверка, у него может не хватить информации. 24 сен. 082008-09-24 13:02:11


0

Это зависит скорее от того, насколько важны эти два условия для рабочего процесса и контекста, с которыми вы имеете дело.

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

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


0

Мое предпочтение заключается в использовании исключений, когда ситуация действительно исключительна.

Например, для нас, как кодеров, естественно, что есть, по сути, файл для обработки. Если файл отсутствует, у вас есть исключительная и, возможно, неустранимая ситуация.

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

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

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


1

Используйте продолжение, особенно в цикле. Большинство исключений создают трассировку стека, которая может стать серьезным ударом по производительности в узком цикле. Вам нужно переопределить fillInStackTrace, чтобы избежать удара.

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


1

Речь идет не о читаемости, а о безопасном программировании. Если вы обнаружили ошибку, вы должны убедиться, что код клиента не сможет ее игнорировать, если он явно не решил это сделать (например, для повтора).

Кроме того, заявления «если» гораздо более уязвимы для случайного искажения логики из-за ручного рефакторинга.

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

P.S. Лично я предпочитаю использовать исключенные исключения. Но это зависит от типа кода, который вы делаете. У Mine нет причин продолжать, если произойдет какое-либо исключение, поэтому я просто продвигаю его до самого стартового кода, где я сообщаю об этом. Исключенные исключения в этом случае меньше.