Каковы плюсы и минусы обработки ошибок в начале и в конце метода

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

Тем не менее, я хотел бы услышать, что вы считаете плюсами и минусами обработки ошибок в начале и в конце метода.

Обработка в начале:

public String GenerateSomeStringData(String data, int value)
{
    if (data == null)
        throw new ArgumentNullException("data");

    if (value <= 0)
        throw new ArgumentException("value must be greater than zero");

    int dataValue;
    if (!int.TryParse(data, out dataValue))
        throw new InvalidOperationException("data does not contain an integer");

    return dataValue * 4 + value / 12;
}

Обработка в конце: (тот же пример)

public String GenerateSomeStringData(String data, int value)
{
    if (data != null)
    {
        if (value > 0) 
        {
            int dataValue;
            if (int.TryParse(data, out dataValue))
            {
                return dataValue * 4 + value / 12;
            }
            else 
                throw new InvalidOperationException("data does not contain an integer");
        }
        else 
            throw new ArgumentException("value must be greater than zero");
    }
    else 
        throw new ArgumentNullException("data");
}

Какие критерии вы используете, когда решаете, как подойти к этому? Удобочитаемость, ремонтопригодность, краткость?


person Kornelije Petak    schedule 06.07.2011    source источник
comment
Все зависит от ситуации. Все, что делает код легким для чтения и понимания.   -  person Martin York    schedule 06.07.2011
comment
Чистый код, вероятно, предпочтет первый вариант. Мне не нужно прокручивать весь метод, чтобы увидеть, что мой ввод недействителен.   -  person CtrlDot    schedule 06.07.2011
comment
Какое это имеет отношение к С++?   -  person George Johnston    schedule 06.07.2011
comment
@George: Вы правы, вопрос на самом деле не зависит от языка. Я удалил неактуальный тег.   -  person Kornelije Petak    schedule 06.07.2011


Ответы (4)


Достоверность ввода должна быть предварительным условием для выполнения метода - поэтому я бы (и делаю) всегда выполните обработку ошибок сначала.

Это имеет следующие преимущества:

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

  • Четкое разделение проблем между обработкой ошибок и логикой выполнения
    в вашем методе: логика проверки не "вкраплена" в логику выполнения.

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

person BrokenGlass    schedule 06.07.2011
comment
Как определить разницу между проверкой ошибок для остановки выполнения метода и проверкой допустимых входных данных для продолжения выполнения метода? Когда вы используете один подход, а когда другой? - person Kornelije Petak; 06.07.2011
comment
@kornelijepetak: Неверный ввод является ошибкой. Каждый метод имеет неявный или явный договор с вызывающими его объектами о том, какие входные данные допустимы, а какие нет. Я думаю, что вы имеете в виду действительный ввод, который должен обрабатываться логикой по-другому, поскольку он представляет собой своего рода граничное условие. В этом случае я бы обработал это сразу после условий ошибки, но как часть основной логики метода. - person BrokenGlass; 06.07.2011
comment
Сначала проверьте наличие ошибок и отсутствующей информации. Затем проверьте правильность ввода после проверки на наличие ошибок. - person Brian Graham; 06.07.2011

Как уже упоминалось, я бы проверил правильность ввода, прежде чем выполнять какую-либо основную логику метода. Это не только имеет логический смысл, но также снижает уровень отступов в вашем коде и гарантирует отсутствие операторов if {}, которые настолько длинны, что вы не можете увидеть else на одном экране.

person cordialgerm    schedule 06.07.2011

Первый способ намного лучше.

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

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

Если ваш код занимает немного больше места, будет сложно отследить закрывающие скобки в циклах if.

person coder net    schedule 06.07.2011

Мое мнение: сначала сделайте проверку состояния ошибки, чтобы четко определить для кого-то, что подходит для вашего метода, а что НЕ подходит.

person Tigran    schedule 06.07.2011