если / еще, хороший дизайн - PullRequest
18 голосов
/ 03 ноября 2010

Является ли приемлемым / хорошим стиль для упрощения этой функции:

bool TryDo(Class1 obj, SomeEnum type)
{
    if (obj.CanDo(type))
    {
        return Do(obj);
    }
    else
    {
        return false;
    }
}

как:

bool TryDo(Class1 obj, SomeEnum type)
{
    return obj.CanDo(type) && Do(obj);
}

Вторая версия короче, но, возможно, менее интуитивно понятна.

Ответы [ 20 ]

4 голосов
/ 03 ноября 2010

Хотя, безусловно, понятно, что такое второй код для компетентного программиста, мне показалось бы более понятным и легким для чтения в более общем случае написать код, как любой другой «если выполнено предварительное условие, выполняй действие, иначе не получится»style.

Этого можно достичь:тип.Например,

return (array.Length > 1)? array[0] : null;

Или

return (curActivity != null)? curActivity.Operate() : 0;

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

if(curSelection != null)
    curSelection.DoSomething();

Мои два цента.

4 голосов
/ 03 ноября 2010

Мне не нравится вторая версия, поскольку я на самом деле не являюсь поклонником использования порядка вычисления подвыражения в условном выражении. Он помещает ожидаемый порядок в подвыражения, которые, по моему мнению, должны иметь равный приоритет (даже если они этого не делают).

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

3 голосов
/ 03 ноября 2010

Проблема побочных эффектов, о которой упоминают некоторые люди, является фиктивной.Никого не должно удивлять, что метод с именем «Do» имеет побочный эффект.

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

3 голосов
/ 03 ноября 2010

IMO все в порядке, если вторая функция не имеет побочных эффектов. Но так как Do () имеет побочные эффекты, я бы пошел с if.

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

См. Блог Эрика Липперта для более подробного объяснения.

1 голос
/ 03 ноября 2010

Нет. Вторая версия

return (obj.CanDo(type) && Do(obj))

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

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

1 голос
/ 03 ноября 2010

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

1 голос
/ 03 ноября 2010

Я думаю, что Тип Class1 должен определить, может ли он, учитывая значение SomeEnum.

Я бы оставил решение о том, может ли он обрабатывать ввод для него, чтобы решить:

bool TryDo(Class1 obj, SomeEnum type)
{
    return obj.Do(type));    
}
1 голос
/ 03 ноября 2010

Я могу ненавидеть это, но как насчет:

if (obj.CanDo(type)) return Do(obj);
return false;

Мне не нравится иметь брекеты для одного вкладыша.

1 голос
/ 04 ноября 2010

Уже есть несколько хороших ответов, но я подумал, что покажу еще один пример (что я считаю) хорошего, читабельного кода.

bool TryDo(Class1 obj, SomeEnum type)
{
    bool result = false;

    if (obj.CanDo(type))
    {
        result = Do(obj);
    }

    return result;
}

Сохраните или уберите фигурные скобки вокруг телаоператор if по вкусу.

Мне нравится этот подход, потому что он иллюстрирует, что результат равен false, если не происходит что-то еще, и я думаю, что он более четко показывает, что Do() что-то делает и возвращает логическое значение, который TryDo() использует в качестве возвращаемого значения.

1 голос
/ 03 ноября 2010

Никогда не делай этого.Держите это простым и интуитивно понятным.

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