Должны ли / или другие утверждения быть организованы редкостью случаев или трудностью иметь дело с ними?

18

В некотором коде, который я пишу прямо сейчас, у меня есть что-то вроде этого:

if (uncommon_condition) {
    do_something_simple();
} else {
    do();
    something();
    long();
    and();
    complicated();
}

Часть меня думает: «Все хорошо, как написано. Сначала должны идти простые дела, а затем более сложные дела». Но другая часть говорит: «Нет! elseКод должен идти под if, потому что ifпредназначен для работы с необычными случаями и elseдля решения всех других случаев». Что является правильным или предпочтительным?

ЭМБЛЕМА
источник
4
Заказ по простоте / понятности условий! Об остальном могут позаботиться оптимизаторы, предсказатели веток и рефакторинг.
Марьян Венема
Вот почему нам платят большие деньги: принимать эти сложные решения.

Ответы:

24

Порядок по их вероятности быть выполненным. Наиболее распространенные, наиболее вероятные и т. Д. Условия должны идти первыми.

«Сложность обращения с ними» должна решаться с помощью структуры кода, абстракции и т. Д. В примере блок else может быть реорганизован для вызова одного метода. Вы хотите, чтобы ваши ifпредложения были на одном абстрактном уровне.

if ( ! LotteryWinner ) {
    GoToWorkMonday();
} else {
    PlanYearLongVacation();
}
radarbob
источник
6
По производительности я могу согласиться. Но опять же, большинство оптимизаторов и предсказателей ветвления вполне способны позаботиться об этом. Для удобства чтения я могу согласиться, если в наиболее вероятном случае будет значительно больше строк, чем в менее вероятном. Но для меня это скорее указывает на необходимость извлечь метод, чем использовать not. Лично я бы сконцентрировался на уходе от notусловий. Доказано, что они вызывают большую когнитивную нагрузку для понимания, чем «положительные» условия, и наносят ущерб читабельности / понятности кода. Я склонен использовать их только в защитных заявлениях.
Марьян Венема
2
@MarjanVenema, я вижу вашу точку зрения по поводу "не". Но двойной минус - это реальное "не" WTF. На днях я столкнулся с этим в нашем коде doesNotAllowxxFiles = false. Достаточно плохо, но потом сделайте этоif(! doesNotAllowxxFiles)
радаробоб
Да, двойные негативы, негативы в сочетании с «и» и / или «(sic!») И негативы в сочетании с методом / «вар» с «Не в названии», каждый раз приводят мой мозг в замешательство :-)
Марьян Венема
если вам трудно понять, что происходит, я думаю, что часто бывает полезно сделать что-то вроде: simpleBool = (! (complexBool || randomfFlag)) &&! randomFlag
TruthOf42
2
Я согласен с вами, за исключением наличия оговорок об охране (которые всегда имеют исключительное условие в ТОЧНОЙ части инструкции IF, а не общее условие).
Роберт Харви
5

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

if (s == null)
     // short code
else 
     // long 
     // code
     // block

более читабельно, чем

if (s != null)
    // long
    // code
    // block
else
    // short code
CWallach
источник
2
почему это более читабельно? Я не вижу различий между ними с точки зрения читабельности
Джон Деметриу
2
@JohnDemetriou Остальное более заметно, если Тогда короткое. Люди сначала сканируют структуру, а затем присваивают ей значение. Код без Else отличается от кода с одним, поэтому сделать Else более заметным становится более понятным. (При прочих равных условиях по вторникам, когда нет дождя и т. Д.)
4

Нет фиксированного правила как такового, я слышал об использовании, но я следую так

if(usual)
{
(more often)
}
else (unusual)
{
(rarely occurring)
}

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


if(x == 0)  // 1
  {x = 1;}  // 2
else
  {x = 2;}  // 3

Для приведенного выше кода ассемблерный код будет примерно таким:

1. 000d 837DFC00        cmpl    $0, -4(%ebp)
   0011 7509            jne .L2

2. 0013 C745FC01        movl    $1, -4(%ebp)
   001a EB07            jmp .L3

    .L2:
3.001c C745FC02         movl    $2, -4(%ebp)

        .L3:

Если условие внутри if истинно, то поток равен 1-> 2 (4 операции).
Если условие внутри if ложно, то поток равен 1-> 3 (3 операции).

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

Сантош Мудхол
источник
2

Я обнаружил, что совершенно противоположный шаблон облегчает чтение кода и уменьшает или исключает вложенные операторы if. Я называю это «перчаткой». (В рассказе истории перчатка должна представлять собой серию задач, которые должны быть успешно решены до того, как будет завершено окончательное задание.) Обрабатывая вначале свои крайние случаи , вы позволяете основной части вашего кода быть чистым и лаконичным:

if(gauntlet_1){ handle the first gauntlet condition }; 
if(gauntlet_2){ handle the second gauntlet condition };
...
// All preconditions (gauntlets) have been successfully handled

// Perform your main task here
Байрон Джонс
источник
Таким образом, часть «ручки с ручкой» должна быть либо передачей управления, например оператором throw или return, либо должна фактически исправлять ошибку. Некоторые люди недовольны рядом выражений if ... return, но я этого не делаю и думаю, что на самом деле, как вы сказали, код легче читать.
1
Если условие перчаток препятствует выполнению функции, она немедленно возвращает ошибку. Если условие рукавицы можно обработать, я делаю это перед тем, как ввести основной текст кода, когда это возможно. В первую очередь я стараюсь избегать вложенных операторов IF, которые, по моему опыту, являются одной из основных причин неясных и трудных для отладки ошибок кодирования.
Байрон Джонс
0

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

Стив Томас
источник
-1

У меня нет фиксированного правила, но обычно я следую этому - во-первых, рассмотрим, где есть пропущенный шаблон проектирования, который будет учитывать это. Если нет, я пишу это так, чтобы условие в if было наиболее понятным. То есть избегать двойных негативов и тому подобного.

Дон брэнсон
источник
-1

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

технократ
источник
это ничего не дает по сравнению с тем, что уже объяснено в предыдущих ответах - programmers.stackexchange.com/a/223093/31260 и programmers.stackexchange.com/a/223520/31260
комнат