Стандарты кодирования / Лучшие практики кодирования в C ++ - PullRequest
9 голосов
/ 10 ноября 2009

Рассмотрим два сегмента кода ниже. Какой из них лучше и почему? если ты есть другая идея, пожалуйста упомянуть. Где я могу найти ответы на такие практики кодирования? если ты осведомлены о любой книге / статье, пожалуйста, поделитесь.

// Код 1

bool MyApplication::ReportGenerator::GenerateReport(){
    bool retval = false;
    do{
        if (!isAdmin()){
            break;
        }
        if (!isConditionOne()){
            break;
        }
        if (!isConditionTwo()){
            break;
        }
        if (!isConditionThree()){
            break;
        }

        retval = generateReport();
    } while(0);
    return retval;
}

// Кодекса2

bool MyApplication::ReportGenerator::GenerateReport(){
    if (!isAdmin()  || !isConditionOne() || !isConditionTwo() || !isConditionThree()){
        return false;
    }
    return generateReport();
}

Чистый код Роберта С. Мартина - хорошая книга, которая имеет дело с этим. Но, я думаю, эта книга склонна к Java.

UPDATE:

  1. Я специально использовал do {} while (0); цикл, поскольку я не хотел использовать goto.

  2. Я хотел избавиться от стольких операторов if и break, поэтому я предложил код 2.

То, что я вижу из ответов, представляет собой смешанный набор ответов как для Code1, так и для Code2. Есть люди, которые также предпочитают goto по сравнению с Кодексом 1 (который я считал лучше).

Ответы [ 17 ]

2 голосов
/ 22 апреля 2011

Моя привычка - избегать блоков if таким образом:

bool MyApplication::ReportGenerator::GenerateReport(){
    bool report = !( isAdmin()        || isConditionOne() || 
                     isConditionTwo() || isConditionThree() );
    return report ? generateReport() : false; 
}
1 голос
/ 10 ноября 2009

Лично я предпочитаю образец 2. Он группирует те элементы, которые не приведут к генерации отчета вместе.

Что касается общих рекомендаций по кодированию, книга Code Complete ( Amazon) является хорошим справочником по вопросам стиля кодирования.

0 голосов
/ 10 ноября 2009

Лично я предпочитаю, чтобы мои циклы for, while и do ... while были реальными. В первом примере кода это не так. Поэтому я бы выбрал пример 2. Или, как уже говорили другие, разбить пример 2 на ряд if ... return операторов.

0 голосов
/ 10 ноября 2009

Code Complete - обычно рекомендуемая книга, в которой подробно рассматриваются такие стилистические вопросы. Также подумайте о том, чтобы взглянуть на некоторые из опубликованных руководств по стилю организации, чтобы узнать, есть ли у них мнения по этому вопросу; Руководство по стилю Google , например.

Что касается того, что я предпочитаю, второй пример гораздо лучше для меня. Первый - это, по сути, злоупотребление конструкцией do {} while, позволяющей избежать использования goto, догматически придерживаясь буквы «избегать gotos любой ценой», в то же время упуская из виду «код для ясности, не используйте неочевидные языковые трюки» ,

Фактически, единственная причина, по которой вообще можно использовать goto, заключается в том, чтобы догматически придерживаться подхода «только одна инструкция возврата на функцию», когда вы можете избежать простого, читабельного

if (!isAdmin()){
    return false;
}
else if (!isConditionOne()){
    return false;    }
else if (!isConditionTwo()){
    return false;    }
else if (!isConditionThree()){
    return false;    }
else
    return generateReport();

Другие мысли?

Не называйте локальные переменные, которые используются для хранения вычисленного состояния успеха, «returnValue» или подобное. Очевидно, что бы вы ни возвращали, это возвращаемое значение, любой, кто может прочитать C, может увидеть, что возвращается. Скажите мне какие вычисления он проводит. Имя «returnValue» не дает мне никакой информации относительно того, что это означает, когда это правда или ложь. В этом примере гораздо более предпочтительным может быть «мог бы сгенерировать репорты» или подобное.

0 голосов
/ 10 ноября 2009
0 голосов
/ 10 ноября 2009

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

Bool MyApplication::ReportGenerator::GenerateReport(int i)
{
  switch(i)
  {
    case 1:
       // do something
       break;
    case 2:
       // do something
       break;
   // etc
 }
 return GeneratReport()
}

Не совсем уверен, каков ваш план, поскольку вы вызываете метод рекурсивно, и в какой-то момент вы захотите покинуть метод.

0 голосов
/ 10 ноября 2009

Я использовал схожее с обоими в разных обстоятельствах, но вы слишком усложнили первое ИМО:

bool MyApplication::ReportGenerator::GenerateReport(){
    bool retval = false;
    if (!isAdmin()){
    }
    else if (!isConditionOne()){
    }
    else if (!isConditionTwo()){
    }
    else if (!isConditionThree()){
    }
    else
        retval = generateReport();
    return retval;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...