Сложность программного обеспечения относится к различным количественным метрикам программного модуля или исходных файлов, таким как количество строк, количество путей, количество функций или сложность дерева вызова функции. Проверка сложности программного обеспечения Polyspace ® повышается, когда эти показатели превышают пороговое значение. Высокая сложность программного обеспечения может указывать на сложность чтения, понимания и отладки кода. Более эффективно поддерживать приемлемый уровень сложности программного обеспечения во время разработки вместо рефакторинга сложных проектов в дальнейшем. Используйте средства проверки сложности программного обеспечения для обнаружения сложных модулей на ранних этапах цикла разработки, чтобы сократить последующие усилия по рефакторингу.
Можно также вычислить абсолютные значения показателей сложности кода для всех файлов и функций. См. раздел Метрики сложности вычислительного кода.
Каждая проверка сложности программного обеспечения соответствует метрике сложности. Polyspace поднимает средство проверки сложности программного обеспечения, когда соответствующая метрика сложности кода превышает пороговое значение.
Пороговые значения по умолчанию для этих шашек соответствуют стандарту сложности кода Hersteller Initiative Software (HIS). См. раздел Показатели сложности кода HIS. Для шашек, отсутствующих в стандарте HIS, пороговые значения по умолчанию достаточно высоки, чтобы показатели сложности кода всегда были ниже порогового значения. Чтобы эффективно использовать эти шашки, укажите для них соответствующий порог.
Определите соответствующий набор пороговых значений для этих шашек в зависимости от оптимальной практики для сценария использования. Например, при анализе новых проектов или недавно разработанного кода может потребоваться сократить использование GOTO операторов путем установки порогового значения Number of goto statements exceeds threshold до нуля. При анализе модулей, содержащих старые библиотеки, может потребоваться установить пороговое значение большего числа.
В зависимости от продукта Polyspace укажите пороговое значение с помощью интерфейса пользователя или интерфейса командной строки. Например:
В продуктах Polyspace desktop или Server в окне выбора Checkers перейдите в раздел Рекомендации > Сложность программного обеспечения и укажите пороговое значение. В командной строке используйте опцию анализа Check Guidelines (-guidelines). См. раздел Проверка нарушений стандартов кодирования.
В расширении «Polyspace as You Code» запустите окно выбора «Checkers» и укажите пороговые значения в узле «Guidelines > Software Complexity».
В Eclipse™ откройте окно выбора Шашки (Checkers) в окне Настроить проект (Configure Project). См. раздел Настройка чекеров для Polyspace в виде кода в Eclipse (Polyspace Bug Finder Access).
В Visual Studio откройте окно выбора «Шашки» в узле «Полиспейс» > «Проект» окна «Параметры». См. раздел Настройка чекеров для Polyspace в виде кода в Visual Studio (Polyspace Bug Finder Access).
В Visual Studio Code откройте окно выбора «Шашки» в командной палитре. См. раздел Настройка чекеров для Polyspace как кода в Visual Studio Code (Polyspace Bug Finder Access).
В командной строке откройте окно выбора Checkers, выполнив команду polyspace-checkers-selection. См. раздел Настройка чекеров для Polyspace в виде кода в командной строке (Polyspace Bug Finder Access).
Чтобы определить сложность программного обеспечения, настройте пороги шашек. Например, задайте пороги шашек, перечисленных в этой таблице.
| Контролер | Порог |
|---|---|
Comment density below threshold | 20 |
Call tree complexity exceeds threshold | 10 |
Number of call occurrences exceeds threshold | 10 |
Language scope exceeds threshold | 400 |
Пороговые значения указывают на приемлемый уровень сложности программного обеспечения. Чтобы выявить проблемы в коде, которые могут привести к повышению уровня сложности, после настройки средств проверки сложности программного обеспечения выполните анализ Polyspace Bug Finder. Рассмотрим этот код:
long long power(double x, int n){
long long BN = 1;
for(int i = 0; i<n;++i){
BN*=x;
}
return BN;
}
double AppxIndex(double m, double f){//Noncompliant
double U = (power(m,2) - 1)/(power(m,2)+2);
double V = (power(m,4) + 27*power(m,2)+38)/(2*power(m,2)+3);
return (1+2*f*power(U,2)*(1+power(m,2)*U*V+ power(m,3)
/power(m,3)*(U-V)))/( (1-2*f*power(U,2)*(1+power(m,2)*U*V
+ power(m,3)/power(m,3)*(U-V))));
}AppxIndex выглядит сложным. Неочевидно, как можно уменьшить сложность. Проверки сложности программного обеспечения помогают определить источники сложности.После анализа Bug Finder настраиваемые шашки поднимаются:
Comment density below thresholdФункции в кодексе не содержат пояснительных замечаний.
Call tree complexity exceeds threshold и Number of call occurrences exceeds threshold: Слишком много вызовов функций по сравнению с количеством определений функций. Эти проверки показывают, что некоторые выражения можно упаковывать в отдельные функции.
Language scope exceeds threshold: Один и тот же операнд повторяется несколько раз. Можно уменьшить количество повторений. Например, функция power вызывается с одинаковыми аргументами несколько раз.
Эти проверки показывают, что функция AppxIndex может затруднить чтение, понимание и отладку кода. Чтобы уменьшить сложность кода, обращайтесь к поднятым проверкам.
Уменьшите сложность кода, решив выявленные проблемы. В этом случае основной причиной повышенных проверок является то, что функция AppxIndex выполняет несколько задач вместо выполнения одной задачи. Например, функция сначала вычисляет U, затем вычисляет Vи, наконец, вычисляет длинное выражение, содержащее оба U и V. Для решения этих проблем выполните рефакторинг функции. AppxIndex чтобы каждая задача была делегирована отдельной функции. Можно разбить длинное выражение на более мелкие части. Например:
// This code calculates effective index of materials as described in
// the formula in 10.1364...
// power(x,n) returns the nth power of x (x^n)
// n is an integer
// x is a double
// return type is long long
long long power(double x, int n){//Compliant
long long BN = 1;
for(int i = 0; i<n;++i){
BN*=x;
}
return BN;
}
// CalculateU(m) calculates the first intermediate variable
// required to calculate polarization
// m is the relative refractive index
// return type is double;
double CalculateU(double m){//Compliant
return (power(m,2) - 1)/(power(m,2)+2);
}
// CalculateV(m) calculates the second intermediate variable
// required to calculate polarization
// m is the relative refractive index
// return type is double;
double CalculateV(double m){//Compliant
return (power(m,4) + 27*power(m,2)+38)/(2*power(m,2)+3);
}
// CalculateMid(m,f) calculates the large term present
// in both numerator and denominator
// of the effective index calculation
// m is the relative refractive index
// f is the fillfactor
// return type is double;
double CalculateMid(double m, double f){//Compliant
double U = CalculateU(m);
double V = CalculateU(m);
return 2*f*power(U,2)*(1+power(m,2)*U*V + power(m,3)/power(m,3)*(U-V));
}
//AppxIndex(m,f) calculates the approximate effective index
// m is the relative refractive index
// f is the fillfactor
//return type is double
double AppxIndex(double m, double f){//Compliant
return (1+CalculateMid(m,f))/( (1-CalculateMid(m,f)));
}Документирование кода с достаточными комментариями.
Разбейте большую сложную задачу, выполняемую AppxIndex на более мелкие и простые задачи, которые затем делегируются отдельным функциям, таким как CalculateU, CalculateV и CalculateMid. Функция power теперь называется реже. Если позже реализовать другую функцию для вычисления мощности и использовать новую функцию вместо текущей, придется сделать меньше замен.
Запишите новые функции для выполнения одной конкретной задачи с минимальным перекрытием их функциональных возможностей. В результате эти функции содержат меньше повторений одних и тех же операндов.
Дополнительные сведения о проверке сложности программного обеспечения см. в документации средства проверки.
В тех случаях, когда не удается выполнить рефакторинг кода, выполните проверку с помощью аннотаций кода. Например, при использовании сложной библиотеки можно выбрать аннотирование проверок, созданных в библиотеке. См. разделы Аннотирование кода и скрытие известных или приемлемых результатов. При аннотировании метрики кода файла или функции соответствующая проверка сложности программного обеспечения также аннотируется тем же комментарием.