Возврат из метода с неявным или явным «else» или с единственным оператором «return»? - PullRequest
18 голосов
/ 06 августа 2010

Некоторые люди считают несколько операторов возврата плохим стилем программирования. Хотя это справедливо для более крупных методов, я не уверен, приемлемо ли это для коротких. Но есть еще один вопрос: должен ли 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;
}

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

Ответы [ 14 ]

22 голосов
/ 06 августа 2010

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

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

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

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

7 голосов
/ 06 августа 2010

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

В свое время структурированное программирование было ХОРОШИМ, особенно как альтернатива спагетти-коду GOTO, который был распространен в винтажных кодах Фортрана и Кобола 1960-х и 1970-х годов.Но с популярностью таких языков, как 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";
    }

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

7 голосов
/ 06 августа 2010

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

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

4 голосов
/ 06 августа 2010

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

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

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

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

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

3 голосов
/ 06 августа 2010

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

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

3 голосов
/ 06 августа 2010

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

2 голосов
/ 06 августа 2010

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

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

1 голос
/ 07 августа 2010

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

Использовать утверждения или 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;
}
1 голос
/ 06 августа 2010

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

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

1 голос
/ 06 августа 2010

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

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