Как стать автором
Обновить

Комментарии 25

НЛО прилетело и опубликовало эту надпись здесь
Если есть условие вида:

if( 2*2 != 4 )
{
    print "наступил конец света"
}
else
{
    print "наступил мир во всем мире"
}


То лучше поменять ветки местами:
if( 2*2 == 4 )
{
    print "наступил мир во всем мире"
}
else
{
    print "наступил конец света"
}
НЛО прилетело и опубликовало эту надпись здесь
Если вы про второе правило, то в коде должен присутствоват возврат управления, например return.
НЛО прилетело и опубликовало эту надпись здесь
На самом деле не всегда такое правило применимо. Я пришёл ровно к таким же принципам, что Вы изложили, собственно, удивился увидев стиль программирования один в один как у себя, только на другом языке.

Первым в операторе условия должен идти не истинный блок, а логически ожидаемый. Например, у нас в Си, если произошла ошибка, мы должны сначала явно обработать ошибку:
char *str = malloc(str_size);
if (!str) {
    // ... сохранение errno, если требуется
    perror("malloc");
    // ...
} else {
    // в невероятно крайне редких случаях этот блок может присутствовать
}

Но в то же время для условных строк условие будет обратным:
if (str) {
    // работа с str
} else {
    // какая-либо другая логика
}


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

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

Авторское, но все хорошее изобретено до нас. Друзья сказали что подобные правила есть в «Совершенном» или в «Чистом» коде. Возможно видели там.
Никогда не понимал Правила 2. Когда нормальные вложенные условия, нормально выделенные отступами, то видна вся логика процедуры, видно при каких условиях куда попадет программа. А если в тексте рандомно рассыпаны return'ы, то тщательно выискивать их по всему тексту становится неудобно.

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

Стараюсь избегать возврата управления через return (2). Мне кажется, что такой вот выход из условного оператора где-то в середине метода, может быть не очевидным при беглом чтении кодом. Поэтому стараюсь return делать только в конце метода.
Решения имеют свои + и -. Это не догма. Если цель упростить за счет снижения уровня вложенности — return помогает. Если нет условий, которые можно явно отделить, лучше один return.
Возврат управления через return хорошо работает для пред-проверок, т.е. в самом начале метода.
С другой стороны, если возникает ситуация, когда необходимо вернуть управление из середины метода, то, с большой долей вероятности, либо с методом что-то не так и нужна декомпозиция, либо, на самом деле, нужен не return, а throw.
+1, именно.
Холливарная статья. Направление мысли конечно правильное, с большинством предложений согласен и всегда на код ревью требую соблюдения.
Но я сильно не согласен с рандомными return`ами в коде, возврат должен быть один, в остальных местах надо поднимать флаг и на каждом этапе алгоритма его анализировать.
Я всю жизнь работаю с легаси, и что бы понять как оно устроено живу с дебагером в обнимку, и меня очень очень вымораживает когда я поставлю брейк поинт до интересного места, а отладчик до него не доходит потому что где то был спрятан return.
В знакомом коде нет проблем с return`ами, но мы же код не для себя пишем? его другие люди читать будут, им всё должно быть понятно, для них поведение должно быть предсказуемо, логично.
По поводу if-then-else, на практике пришёл к тому что писать
var = expression(a,b,c);
if(var) method1();
if(!var)method2();

сильно удобней и ветки местами менять, и от веток отказываться, вот это всё удобней, и более модульно код смотрится.
Про код в котором строчки сгруппированы правильно сказано — такой код глотаешь, жевать его не приходиться. И опять же шаги алгоритма местами менять удобней.
в остальных местах надо поднимать флаг и на каждом этапе алгоритма его анализировать.
Вот уж воистину лекарство хуже болезни.
Разбросанные по методу return'ы — это конечно зло в разрезе анализа потока выполнения, но флаги — это зло в квадрате.
Я когда первый раз увидел тоже ругался на индусов, но потом (через пару лет) сам к этому пришёл. Флаг же обычно один и код метода не такой длинный что бы сбиться со счёта.
Кто к чему привык. Для меня множественные ретурны — это предельная степень ада.
Вы сравниваете разные вещи. Флаг у вас один, а ретурны, почему-то, множественные.
Там, где достаточно одного флага — там достаточно и одного возврата. К тому же, оператор возврата однозначен — т.е. если он появился в коде, то это однозначное и единственное место возврата управления. В случае с флагом необходимо держать его в уме при анализе всего оставшегося кода, гадая, где же вы его могли еще проглядеть.

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

И сильно JNZ проигрывает в производительности JZ?

Некорректно так сравнивать. Из разряда «с какого конца я съем быстрее бутерброд?»
Вам намекают что овчинка не стоит выделки. Вероятность того или иного варианта зависит от использования кода, от пользовательских привычек, от характера данных, со временем это меняется.

Не надо тратить время на преждевременную оптимизацию.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации