Лучший способ обработать типичное исключение предусловия? - PullRequest
3 голосов
/ 11 июля 2009

Какой из следующих способов справиться с этим предварительным условием является более желательным, и каковы наиболее важные последствия?

1:

If Not Exists(File) Then 
    ThrowException
    Exit
End If
File.Open
...work on file...

2

If Exists(File) Then 
    File.Open 
    ....work on file...
Else
    ThrowException
    Exit
End 

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

Ответы [ 6 ]

4 голосов
/ 11 июля 2009

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

2 голосов
/ 12 июля 2009

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

1 голос
/ 12 июля 2009

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

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

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

1 голос
/ 11 июля 2009

Каждое исключение должно быть произведено на соответствующем уровне.В этом случае вашим исключением является проблема open (), которая обрабатывается вызовом open ().Следовательно, вы не должны добавлять код исключения в вашу подпрограмму, потому что вы дублируете вещи.Это верно, если:

  1. вы не хотите абстрагировать свой бэкэнд ввода-вывода (скажем, ваша подпрограмма высокого уровня может использовать либо открытие файла, но и MySQL в будущем).В этом случае для клиентских кодов было бы лучше знать, что более стандартное и уникальное исключение будет создано, если возникнут проблемы ввода-вывода
  2. . Наличие исключения низкого уровня подразумевает исключение более высокого уровня с семантической высокоуровневойНапример, невозможность открыть файл пароля означает, что аутентификация невозможна, и поэтому вам следует вызвать что-то вроде UnableToAuthenticateException,Я ненавижу длинные блоки кода, в частности, под ifs.Они также имеют тенденцию к гнездованию, и если вы выберете вторую стратегию, вы в конечном итоге сделаете слишком много отступов.
1 голос
/ 11 июля 2009

Читаемость первого подхода выше, чем второго.
Второй вариант может быть достаточно быстрым, если у вас есть несколько предварительных условий для проверки; более того, он предполагает, что if / else каким-то образом находится в нормальном потоке, в то время как это действительно только для исключительных ситуаций.

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

По этим двум причинам я бы определенно выбрал первый вариант.


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

1 голос
/ 11 июля 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...