Подтвердить что ты не робот

Что лучше стиль кодирования?

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

Ниже приведены некоторые упрощенные примеры кода.

Вложенные:

If(condition1)
{
    If(condition2)
    {
        if(condition3)
        {
            return true;
        }
        else
        {
            log("condition3 failed");
        }
    else
    {
        log("condition2 failed")
    }
}
else
{
    log("condition1 failed")
}

return false;

или

Bool Driven:

bool bRC = false;

bRC = (condition1);
if(brc)
{
    bRC = (condition2);
}
else
{
    log("condition1 failed");
    return false;
}

if(bRC)
{
    bRC = (condition3);
}
else
{
    log("condition2 failed");
    return false;
}

if(bRC)
{
    return true;
}
else
{
    log("condition3 failed");
    return false;
}
4b9b3361

Ответ 1

Мне нравится твоя лучше, но я бы, наверное, сделал что-то вроде:

if (condition1 && condition2 && condition3)
{
    return true;
}
else if (!condition1)
{
    log("condition1 failed");
}
else if (!condition2)
{
    log("condition2 failed");
}
else
{
    log("condition3 failed");
}
return false;

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

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

Ответ 2

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

if(!condition1)
{
    log("condition1 failed");
    return false;
}

if(!condition2)
{
    log("condition2 failed");
    return false;
}

if(!condition3)
{
    log("condition3 failed");
    return false;
}

return true;

Возможно, это равнодушное отвращение колена к супер-гнездованию, но оно, безусловно, более чистое, чем его дерьмо, сохраняющее логические условия в определенных значениях. Однако он может быть менее читаемым в контексте: рассмотрим, было ли одно из условий isreadable(). Яснее сказать if(isreadable()), потому что мы хотим знать, что-то читаемо. if(!isreadable()) предлагает, хотим ли мы знать, не читается ли это, что не является нашим намерением. Это, конечно, спорно, что может возникнуть ситуации, когда один является более удобным для чтения/понятнее, чем другие, но я фанат этого пути самого. Если кто-то повесил трубку на возврат, вы можете сделать это:

if(!condition1)
    log("condition1 failed");

else if(!condition2)
    log("condition2 failed");

else if(!condition3)
    log("condition3 failed");

else
    return true;

return false;

Но это, скорее, недостаточно, и менее "ясное", на мой взгляд.

Ответ 3

Я лично считаю, что вложенный код значительно легче читать.

Ответ 4

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

Ответ 5

Как и вложенная версия, но гораздо более чистая для меня:

if not condition1:
    log("condition 1 failed")
else if not condition2:
    log("condition 2 failed")
else if not condition3:
    log("condition 3 failed")
else
    return true;
return false;

Остерегайтесь, чтобы каждое условие оценивалось один раз.

Ответ 6

Второй стиль абсурдно многословен: действительно ли он предлагал именно это? Вам не нужны большинство этих операторов if, потому что в части else есть return.

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

Ни один из них не кажется мне удовлетворительным.

Ответ 7

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

Ответ 8

Я думаю, что оба пути возможны и имеют свои "за" и "против". Я бы использовал стиль, управляемый bool, в случаях, когда у меня было бы действительно глубокое вложение (8 или 10 или что-то в этом роде). В вашем случае с 3 уровнями, я бы выбрал ваш стиль, но для точного образца сверху, я бы пошел так:

void YourMethod(...)
{
  if (condition1 && condition2 && consition3)
    return true;

  if (!condition 1)
    log("condition 1 failed");

  if (!condition 2)
    log("condition 2 failed");

  if (!condition 3)
    log("condition 3 failed");

  return result;
}

... или нравится, если вы предпочитаете одну точку выхода (например, я делаю)...

void YourMethod(...)
{
  bool result = false;

  if (condition1 && condition2 && consition3)
  { 
    result = true;
  }
  else
  {
    if (!condition 1)
      log("condition 1 failed");

    if (!condition 2)
      log("condition 2 failed");

    if (!condition 3)
      log("condition 3 failed");
  }
  return result;
}

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

Ответ 9

Я бы, вероятно, пошел с

   if (!condition1)      log("condition 1 failed");
   else if (!condition2) log("condition 2 failed");
   else if (!condition3) log("condition 3 failed");
   // -------------------------------------------
   return condition1 && condition2 && condition3;

который, я считаю, является равноценным и намного более чистым...

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

   if (!condition1) log("condition 1 failed");
   if (!condition2) log("condition 2 failed");
   if (!condition3) log("condition 3 failed");
   // -------------------------------------------
   return condition1 && condition2 && condition3;

Ответ 10

Если язык поддерживает обработку исключений, я бы пошел со следующим:

try {
    if (!condition1) {
        throw "condition1 failed";
    }

    if (!condition2) {
        throw "condition2 failed";
    }

    if (!condition3) {
        throw "condition3 failed";
    }

    return true;

} catch (e) {
    log(e);
    return false;
}

EDIT От charles bretana: см. Использование исключений для потока управления

Ответ 11

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

if (!condition1) {
    log("condition1 failed");
    return false;
}
if (!condition2) {
    log("condition2 failed");
    return false;
}
if (!condition3) {
    log("condition3 failed");
    return false;
}
return true;

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

result = true;
if (!condition1) {
    log("condition1 failed");
    result = false;
}
if (!condition2) {
    log("condition2 failed");
    result = false;
}
if (!condition3) {
    log("condition3 failed");
    result = false;
}
return result;

Ответ 12

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

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

Слишком много реализаций в зависимости от ваших потребностей, поэтому создание примера кода будет бессмысленным.

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

Ответ 13

Код должен повторить проблему на указанном языке. Поэтому я утверждаю, что либо фрагменты могут быть "лучше". Это зависит от моделируемой модели. Хотя я предполагаю, что ни одно из решений не будет параллельным фактической проблеме. Если вы ставите реальные условия вместо условия1,2,3, это может полностью изменить "лучший" код.
Я подозреваю, что есть лучший (3d) способ написать все вместе.

Ответ 14

if( condition1 && condition2 && condition3 )
    return true;

log(String.Format("{0} failed", !condition1 ? "condition1" : (!condition2 ? "condition2" : "condition3")));
return false;

Таким образом, вам не нужно видеть много строк кода только для ведения журнала. И если все ваши условия верны, вы не тратите время на их оценку, если вам приходится регистрироваться.