Как объяснить разработчику, что добавление дополнительный, если - еще, если условия не хороший способ “улучшить” удобочитаемость?

Недавно я врезался в следующий код C++:

if (a)
{
  f();
}
else if (b)
{
  f();
}
else if (c)
{
  f();
}

Где a, b и c являются всеми различными условиями, и они не очень коротки.

Я пытался изменить код на:

if (a || b || c)
{
  f();
}

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

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

2) Это не самый быстрый код, и никакой компилятор не оптимизирует это.

Но мои аргументы не убедили его.

Что Вы сказали бы программисту, пишущему такой код?

Вы думаете, что сложное условие еще является оправданием за использование если вместо ИЛИ?

9
задан Lilit 9 June 2010 в 14:00
поделиться

9 ответов

Замените три сложных условия одной функцией, делая очевидным, почему f() должна быть выполнена.

bool ShouldExecute; { return a||b||c};
...
if ShouldExecute {f();};
12
ответ дан 4 December 2019 в 06:09
поделиться

Производительность здесь не проблема.

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

Иногда я делаю это так, иногда - другим. Я думаю о том -

«Каким образом будет легче редактировать виды изменений, которые, возможно, придется внести в будущем?»

Не переживайте по мелочам.

2
ответ дан 4 December 2019 в 06:09
поделиться

В целом я думаю, что вы правы в этом if (a || b || c) {f (); } легче читать. Он также мог хорошо использовать пробелы, чтобы помочь разделить три блока.

Тем не менее, мне было бы интересно посмотреть, как выглядят a , b , c и f . Если f - это всего лишь вызов одной функции, и каждый блок имеет большой , я могу как бы понять его точку зрения, хотя меня раздражает нарушение принципа DRY, вызывая f ] три разных раза.

2
ответ дан 4 December 2019 в 06:09
поделиться

Я думаю, что оба ваших аргумента (а также аргумент Developer Art о сопровождаемости) являются обоснованными, но, очевидно, ваш партнер по дискуссии не готов к обсуждению.

У меня такое чувство, что вы ведете эту дискуссию с кем-то, кто считается более старшим. Если это так, то вам нужно вести войну, а это всего лишь одна маленькая битва, победа в которой для вас не важна. Вместо того чтобы тратить время на споры по этому поводу, постарайтесь сделать так, чтобы ваши результаты (которые будут намного лучше, чем у вашего партнера по дискуссии, если он пишет такой код) говорили сами за себя. Просто убедитесь, что вы получаете благодарность за свою работу, а не вся команда или кто-то другой.

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

1
ответ дан 4 December 2019 в 06:09
поделиться

Производительность даже не должна подвергаться сомнению

Возможно, позже он не будет вызывать f () во всех трех условиях

0
ответ дан 4 December 2019 в 06:09
поделиться

Я очень сомневаюсь, что это приведет к увеличению производительности, за исключением, по крайней мере, очень специфического сценария. В этом сценарии вы меняете a, b и c, и, таким образом, какой из трех, который запускает код, изменяется, но код все равно выполняется, а затем сокращение кода до одного оператора if может улучшить, поскольку ЦП может иметь код в кеш ветки, когда он доберется до него в следующий раз. Если вы утроите код, так что он будет занимать в 3 раза больше места в кэше ветвления, высока вероятность того, что один или несколько путей будут вытеснены, и, следовательно, у вас не будет наиболее производительного выполнения.

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

Что касается удобочитаемости, которую легче читать:

  • если что-то, сделайте это
  • если что-то еще, сделайте это
  • если еще что-то еще, сделайте это
  • «это» - это то же самое во всех трех случаях

или в этом:

  • если что-то, или что-то еще, или еще что-то еще, тогда сделайте это

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

Из-за этого снижается ремонтопригодность при использовании организации с тремя операторами if.

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

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

Теперь давайте предположим, что части «a», «b» и «c» действительно большие, так что операционная система там теряется в большом количестве шума с круглыми скобками или чем-то еще.

Я бы все равно реорганизовал код так, чтобы он вызывал функцию (или выполнял код там) только в одном месте, так что, возможно, это компромисс?

bool doExecute = false;
if (a) doExecute = true;
if (b) doExecute = true;
if (c) doExecute = true;
if (doExecute)
{
    f();
}

или, что еще лучше, этот способ воспользоваться преимуществом логического логическое короткое замыкание, чтобы не оценивать ненужные вещи:

bool doExecute = a;
doExecute = doExecute || b;
doExecute = doExecute || c;
if (doExecute)
{
    f();
}
1
ответ дан 4 December 2019 в 06:09
поделиться

Этот код избыточен. Он склонен к ошибкам.

Если вы однажды замените f(); на что-то другое, есть опасность пропустить одну ошибку.


Однако может быть мотивация, что эти три тела условий могут однажды стать разными, и вы как бы готовитесь к этой ситуации. Если есть большая вероятность, что это произойдет, то можно сделать что-то подобное. Но я бы посоветовал следовать принципу YAGNI (You Ain't Gonna Need It). Не могу сказать, сколько раздутого кода было написано не из-за реальной необходимости, а просто в ожидании, что он понадобится завтра. Практика показывает, что это не приносит никакой пользы в течение всего срока службы приложения, но сильно увеличивает накладные расходы на обслуживание.


Что касается того, как подойти к объяснению этого коллеге, то этот вопрос уже много раз обсуждался. Посмотрите здесь:

Как сказать кому-то, что он пишет плохой код?

Как оправдаться перед коллегами, что они создают плохой код?

Как справиться с некачественным кодом от членов команды?

"Наставник" старшего программиста или коллеги без оскорблений

21
ответ дан 4 December 2019 в 06:09
поделиться

Повторение кода не делает вещи яснее, ваш (a|||b||c) намного яснее, хотя, возможно, можно было бы рефакторить его еще больше (поскольку это C++), например,

x.f()
0
ответ дан 4 December 2019 в 06:09
поделиться

Поскольку условия длинные, пусть он сделает так:

if ( (aaaaaaaaaaaaaaaaaaaaaaaaaaaa)
  || (bbbbbbbbbbbbbbbbbbbbbbbbbbbb)
  || (cccccccccccccccccccccccccccc) )
{
    f();
}

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

5
ответ дан 4 December 2019 в 06:09
поделиться
Другие вопросы по тегам:

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