Подтвердить что ты не робот

Возврат из метода с неявным или явным "else" или с помощью одного выражения "return"?

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

Неявный 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;
}

Какой из них вы бы предпочли? Другие предложения?

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

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

Ответ 3

Догма "единственной точки выхода" исходит из дней структурированного программирования.

В свое время структурированное программирование было ХОРОШЕЙ ВЕЩЕЙ, особенно в качестве альтернативы GOTO-коду спагетти, который был распространен в 1960 и 1970 годах в винтажном коде Fortran и Cobol. Но с популярностью таких языков, как Pascal, 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";

На первый взгляд похоже, что результат будет "Hello again", если i меньше 10, а j больше 10. На самом деле это неверное истолкование - нас обманули неправильным отступом, Но если код был написан с { } вокруг тех частей, было бы ясно, что отступ был неправильным; например.

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

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

Ответ 4

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

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

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

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

Я нахожу это более ясным, как это для этих типов методов.

Ответ 5

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

Ответ 6

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

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

Ответ 7

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

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

Ответ 8

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

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

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

Ответ 9

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

Ответ 10

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

Я никогда не сталкивался с этим "правилом" применительно к методам вне академических кругов, и я действительно не вижу смысла. Вы в основном должны зафрахтовать свой код, чтобы повиноваться правилу, с дополнительными переменными и так далее, и никоим образом вы не можете убедить меня, что это хорошая идея. Любопытно, что если вы напишете его естественным образом в соответствии с вашим первым вариантом, компилятор обычно генерирует код в соответствии с правилом в любом случае... так что вы можете утверждать, что правило соблюдается: только не вами; -)

Ответ 11

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

Использовать утверждения или RuntimeExceptions

    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;
}

Ответ 12

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

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

Ответ 13

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

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

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

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

Ответ 14

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

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