Наиболее читаемый способ форматировать длинные, если условия? [закрыто

softwareengineering.stackexchange https://softwareengineering.stackexchange.com/questions/3450

  •  16-10-2019
  •  | 
  •  

Вопрос

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

if (FoobarBaz::quxQuux(corge, grault) || !garply(waldo) || fred(plugh) !== xyzzy) {
    thud();
}

или же

if (
    FoobarBaz::quxQuux(corge, grault)
 || !garply(waldo)
 || fred(plugh) !== xyzzy
) {
    thud();
}

или же

if (FoobarBaz::quxQuux(corge, grault)
    || !garply(waldo)
    || fred(plugh) !== xyzzy) {
    thud();
}

или же

thudable = FoobarBaz::quxQuux(corge, grault);
thudable ||= !garply(waldo);
thudable ||= fred(plugh) !== xyzzy;

if (thudable) {
    thud();
}

или какие -либо другие предпочтения?

Это было полезно?

Решение

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

if (bar || baz || quux) { ... }

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

function foo() {
  return bar || baz || quux;
}

if (foo()) { ... }

Другие советы

Мне нравится держать операторов в конце, чтобы указать продолжение:

if (the_function_being_called() != RETURNCODE_SUCCESS &&
    the_possibly_useful_recovery_strategy() == RETURNCODE_EPICFAIL &&
    this_user_has_elected_to_recieve_error_reports)
{
    report_error();
}

Я большой поклонник значимых имен переменных:

const bool isInAStrangeCondition =
    FoobarBaz::quxQuux(corge, grault) ||
    !garply(waldo) ||
    fred(plugh) !== xyzzy;

if (isInAStrangeCondition) {
    thud();
}

Или рефактор как функция, как упомянуто выше.

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

bool goodblah = some_mess < whatever;
bool frobnacious = messy_crud != junky_expression;
bool yetanother = long_winded_condition;

if (goodblah || (frobnacious && yetanother))   {
    ...
}

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

Я склонен выравнивать операторов в начале новых линий, поэтому я помню, как я объединяю термины (как для длинной логики, так и для длинной арифметики). Как это:

if (first_attempt(data) == SUCCESS
    || (reusable(data) && second_attempt(data) == SUCCESS)
    || (still_reusable(data) && third_attempt(data) == SUCCESS))
  return SUCCESS;

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

Я фанат следующего:

if (really_long_expression && another_really_really_long_expression && 
            another_very_long_expression_OMG_id_it_long){
    bugs();
}

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

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

Лицензировано под: CC-BY-SA с атрибуция
scroll top