Возврат из метода с неявным или явным “еще” или с единственным оператором “возврата”?

Некоторые люди рассматривают несколько операторов возврата как плохой стиль программирования. В то время как это верно для больших методов, я не уверен, приемлемо ли это для коротких. Но существует другой вопрос: Если else явно будьте записаны, если существует оператор возврата в предыдущем if?

Неявный else:

private String resolveViewName(Viewable viewable) {
    if(viewable.isTemplateNameAbsolute())
        return viewable.getTemplateName();
    return uriInfo.getMatchedResources().get(0).getClass().toString();
}

Явный else:

private String resolveViewName(Viewable viewable) {
    if(viewable.isTemplateNameAbsolute())
        return viewable.getTemplateName();
    else
        return uriInfo.getMatchedResources().get(0).getClass().toString();
}

Технически else не необходимо здесь, но это имеет более очевидный смысл.

И возможно самый чистый подход с единственным возвратом:

private String resolveViewName(Viewable viewable) {
    String templateName;
    if(viewable.isTemplateNameAbsolute())
        templateName = viewable.getTemplateName();
    else
        templateName = uriInfo.getMatchedResources().get(0).getClass().toString();
    return templateName;
}

Какой Вы предпочли бы?Другие рекомендации?

18
задан deamon 6 August 2010 в 12:28
поделиться

14 ответов

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

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

0
ответ дан 30 November 2019 в 06:19
поделиться

Другое очевидное предложение: используйте условный оператор.

private String resolveViewName(Viewable viewable) {
    return viewable.isTemplateNameAbsolute()
        ? viewable.getTemplateName()
        : uriInfo.getMatchedResources().get(0).getClass().toString();
}

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

(С другой стороны, я бы предложил использовать фигурные скобки для всех if блоков, даже для блоков с одним оператором.)

22
ответ дан 30 November 2019 в 06:19
поделиться

Догма «единой точки выхода» пришла со времен структурного программирования.

В свое время структурированное программирование было ХОРОШО, особенно как альтернатива спагетти-коду, основанному на GOTO, который был распространен в старинном коде Fortran и Cobol 1960-х и 1970-х годов. Но с ростом популярности таких языков, как Паскаль, C и т. Д., С их более богатым набором управляющих структур, структурированное программирование было ассимилировано в массовое программирование, и некоторые догматические аспекты утратили свою популярность. В частности, большинство разработчиков рады иметь несколько выходов из цикла или метода ... при условии, что это упрощает понимание кода.

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

Но @Jon Skeet указал на гораздо более серьезную стилистическую проблему с вашим кодом; т.е. отсутствие блоков {} вокруг операторов then и else. На мой взгляд, код действительно должен быть написан так:

private String resolveViewName(Viewable viewable) {
    if (viewable.isTemplateNameAbsolute()) {
        return viewable.getTemplateName();
    } else {
        return uriInfo.getMatchedResources().get(0).getClass().toString();
    }
}

Это не просто проблема красивости кода. На самом деле есть серьезный смысл всегда использовать блоки. Примите во внимание следующее:

String result = "Hello"
if (i < 10) 
    result = "Goodbye";
    if (j > 10) 
         result = "Hello again";

На первый взгляд кажется, что результатом будет «Привет снова», если i меньше 10, а j больше 10. Фактически, то есть неправильное прочтение - нас обманули неправильным отступом.Но если бы код был написан с помощью {} вокруг тогдашних частей, было бы ясно, что отступ был неправильным; например

String result = "Hello"
if (i < 10) {
    result = "Goodbye";
    }
    if (j > 10) {
         result = "Hello again";
    }

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

7
ответ дан 30 November 2019 в 06:19
поделиться

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

Лично мне нравится обходиться без остального. Если кто-то просматривает ваш код, велики шансы, что он не слишком запутается без else.

0
ответ дан 30 November 2019 в 06:19
поделиться

Я предпочитаю первый.

Или ... вы можете использовать if return else return для столь же важных бифуркаций и if return return для особых случаев.

Когда у вас есть утверждения ( if p == null return null ), то первое из них на сегодняшний день является наиболее ясным. Если у вас есть варианты с одинаковым весом ... Я считаю, что можно использовать явное else.

1
ответ дан 30 November 2019 в 06:19
поделиться

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

1
ответ дан 30 November 2019 в 06:19
поделиться

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

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

2
ответ дан 30 November 2019 в 06:19
поделиться

Я обычно предпочитаю первый вариант, так как он самый короткий.

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

Кроме того, в длинных методах есть случаи, когда вам может потребоваться сделать что-то вроде

if(!isValid(input))  { return null; }// or 0, or false, or whatever
// a lot of code here working with input

Я считаю, что это еще более понятно для таких типов методов.

4
ответ дан 30 November 2019 в 06:19
поделиться

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

3
ответ дан 30 November 2019 в 06:19
поделиться

Поскольку вы просили другие предложения, как насчет

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

    private String resolveViewName(Viewable viewable) {
    if(viewable.isTemplateNameAbsolute())
        return viewable.getTemplateName();
    else
        return uriInfo.getMatchedResources().get(0).getClass().toString();
    throw new RuntimeException ( "Unreachable Code" ) ;
    }

Использовать последнее ключевое слово

private String resolveViewName(Viewable viewable) {
final String templateName;
if(viewable.isTemplateNameAbsolute())
    templateName = viewable.getTemplateName();
else
    templateName = uriInfo.getMatchedResources().get(0).getClass().toString();
return templateName;
}
1
ответ дан 30 November 2019 в 06:19
поделиться

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

1.) Код никогда не должен быть умным.

7
ответ дан 30 November 2019 в 06:19
поделиться

Сведения об одном операторе возврата относятся к 1970-м годам, когда Дейкстра и Вирт занимались структурным программированием. Они с большим успехом применили его к контрольным структурам, которые теперь обосновались в соответствии с их предписанием - один вход и один выход. Раньше в Фортране было несколько записей в подпрограмме (или, возможно, функции, извините, прошло около 35 лет с тех пор, как я их написал), и это функция, которую я никогда не упускал, на самом деле я не думаю, что когда-либо использовал ее.

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

1
ответ дан 30 November 2019 в 06:19
поделиться

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

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

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

В конце концов, все сводится к личным предпочтениям (как и многое другое в стиле программирования).

0
ответ дан 30 November 2019 в 06:19
поделиться

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

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

3
ответ дан 30 November 2019 в 06:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: