Приветствую Вас ГостьВторник, 14.05.2024, 00:40

Каталог статей


Стив Макконнелл "Совершенный код". Условные операторы

Операторы if

Простые операторы if-then

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

Убедитесь, что при сравнении на равенство ветвление корректно Использование > вместо >= или < вместо <= — это аналог ошибки потери единицы при обращении к массиву или вычислении индекса цикла.

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

Размещайте осмысленные выражения после оператора if.

Плохой код:

if ( SomeTest )
   ;
else {
   // делаем что-то
   ...
}

Хороший код:

if ( ! someTest ) {
   // делаем что-то
   ...
}

Рассмотрите вопрос использования блока else

Если вы задаете if#проверку, не имеющую блока else, то, кроме очевидных случаев, пишите в комментариях объяснение, почему else отсутствует

// Если цвет задан корректно.
if ( COLOR_MIN <= color && color <= COLOR_MAX ) {
   // Делаем чтото
   ...
}
else {
   // Иначе цвет задан некорректно.
   // Вывод на экран не выполняется – просто игнорируем команду.
}

Проверяйте корректность выражения else При тестировании кода вы можете решить, что достаточно проверить основной блок if и все. Однако, если можно проверить вариант в else, не забудьте это сделать.
Проверяйте возможную перестановку блоков if и else Частая ошибка при программировании выражений if-then состоит в размещении кода из блока if в блоке else, т. е. инвертировании логики выражения if. Проверяйте ваш код на наличие этой ошибки.

Заменяйте негативные выражения позитивными, меняя местами блоки if и else. Пример сбивающего с толку отрицательного логического условия (Java)
Здесь оператор отрицания.
if ( !statusOK ) {
   // Делаем что-то.
   ...
}
else {
   // Делаем что-то еще.
   ...
}

Это условие можно заменить другим, выраженным положительно:

if ( statusOK ) {
   // Делаем что-то еще.
   //Код в этом блоке был поменян местами...
   ...
}
else {
   //...с кодом в этом блоке.
   // Делаем что-то.
   ...
}

Упрощайте сложные проверки с помощью вызовов логических функций. Вместо кода:

if ( inputCharacter < SPACE ) {
   characterType = CharacterType_ControlCharacter;
}
else if (
   inputCharacter == ‘ ‘ ||
   inputCharacter == ‘,’ ||
   inputCharacter == ‘.’ ||
   inputCharacter == ‘!’ ||
   inputCharacter == ‘(‘ ||
   inputCharacter == ‘)’ ||
   inputCharacter == ‘:’ ||
   inputCharacter == ‘;’ ||
   inputCharacter == ‘?’ ||
   inputCharacter == ‘-’
) {
   characterType = CharacterType_Punctuation;
}

лучше было написать

if ( IsControl( inputCharacter ) ) {
   characterType = CharacterType_ControlCharacter;
}
else if ( IsPunctuation( inputCharacter ) ) {
   characterType = CharacterType_Punctuation;
}

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

Убедитесь, что учтены все варианты Закодируйте в последнем блоке else сообщение об ошибке или утверждение, чтобы отловить ситуации, которые вы не планировали.

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

Пример выражения, содержащего слишком мало скобок (Java)
if ( a < b == c == d ) ...

Пример выражения, частично улучшенного с помощью скобок (Java)
if ( ( a < b ) == ( c == d ) ) ...

Заключайте в скобки логическое выражение целиком Скобки ничего вам не стоят, а читабельность улучшают.

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

MIN_ELEMENTS <= i and i <= MAX_ELEMENTS

MIN_ELEMENTS и MAX_ELEMENTS — это две граничные точки, и поэтому они расположены по краям выражения. Подразумевается, что переменная i должна находиться между ними, и поэтому она расположена в середине.

Этот подход более очевиден, чем такие условия, как:
( i > MIN_ELEMENTS ) and ( i < MAX_ELEMENTS )

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

if ( inputStatus == InputStatus_Success ) {
   // Много кода.
   ...
   if ( printerRoutine != NULL ) {
      // Много кода.
      ...
      if ( SetupPage() ) {
         // Много кода.
         ...
         if ( AllocMem( &printData ) ) {
            // Много кода.
            ...
          }
      }
   }
}

Вот как можно видоизменить этот код, используя повторные проверки, а не вложенность:

if ( inputStatus == InputStatus_Success ) {
   // Много кода.
   ...
   if ( printerRoutine != NULL ) {
      // Много кода.
      ...
   }
}

if ( ( inputStatus == InputStatus_Success ) &&
   ( printerRoutine != NULL ) && SetupPage() ) {
   // Много кода.
   ...

   if ( AllocMem( &printData ) ) {
      // Много кода.
      ...
   }
}

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

Преобразуйте вложенные if в набор if-then-else

Пример заросшего дерева решений (Java)
if ( 10 < quantity ) {
   if ( 100 < quantity ) {
      if ( 1000 < quantity ) {
         discount = 0.10;
      }
   else {
      discount = 0.05;
   }
}
else {
   discount = 0.025;
   }
}
else {
   discount = 0.0;
}

Вы можете преобразовать этот код таким образом:

if ( 1000 < quantity ) {
   discount = 0.10;
}
else if ( 100 < quantity ) {
   discount = 0.05;
}
else if ( 10 < quantity ) {
   discount = 0.025;
}
else {
   discount = 0;
}

Преобразуйте вложенные if в оператор case. Тот же самый пример можно было написать следующим образом:

Select Case quantity
   Case 0 To 10
      discount = 0.0
   Case 11 To 100
      discount = 0.025
   Case 101 To 1000
      discount = 0.05
   Case Else
      discount = 0.10
End Select

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

В C-подобных языках, помещайте константы с левой стороны сравнений 

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

if ( MIN_ELEMENTS = i ) ...

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

if ( i = MIN_ELEMENTS ) ...

В этом случае компилятор, напротив, выдаст только предупреждение, и лишь в том случае, если у вас включены все предупреждения компилятора

 

Категория: Стив Макконнелл "Совершенный код" | Добавил: leshic (11.11.2021)
Просмотров: 237 | Рейтинг: 0.0/0
Всего комментариев: 0
Имя *:
Email *:
Код *:
Вход на сайт
Поиск
Категории раздела
Стив Макконнелл "Совершенный код" [20]
Стив Макконнелл "Совершенный код"
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0