Уменьшите сложность программного обеспечения при помощи Polyspace Checkers

Сложность программного обеспечения относится к различным количественным метрикам программного модуля или исходных файлов, таким как количество линий, количество путей, количество функций или сложность дерева вызова функции. Polyspace® проверки сложности программного обеспечения возникают, когда эти метрики превышают порог. Высокая сложность программного обеспечения может указать, что ваш код трудно считать, понимать и отлаживать. Более эффективно поддерживать приемлемый уровень сложности программного обеспечения во время разработки вместо рефакторинга сложных проектов в дальнейшем. Используйте проверки сложности программного обеспечения для обнаружения сложных модулей в начале цикла разработки, чтобы уменьшить последующие усилия по рефакторингу.

Можно также вычислить абсолютные значения метрик сложности кода для всех файлов и функций. См. «Вычисление Метрик сложности кода».

Сконфигурируйте пороги для проверки сложности программного обеспечения

Каждая проверка сложности программного обеспечения соответствует метрике сложности. Polyspace поднимает проверку сложности программного обеспечения, когда соответствующая метрика сложности кода превышает порог.

Пороги по умолчанию для этих шашек соответствуют стандарту сложности кода Hersteller Initiative Software (HIS). См. «Метрики сложности кода HIS». Для шашек, которые не присутствуют в стандарте HIS, пороги по умолчанию достаточно высоки, чтобы метрики сложности кода вашего кода всегда могли быть ниже порога. Чтобы эффективно использовать эти шашки, укажите для них соответствующий порог.

Определите соответствующий набор порогов для этих шашек в зависимости от наилучшей практики для вашего случая использования. Например, при анализе новых проектов или только что разработанного кода можно уменьшить использование GOTO операторы путем установки порога Number of goto statements exceeds threshold в нуль. При анализе модулей, содержащих устаревшие библиотеки, может потребоваться задать более высокое пороговое значение.

В зависимости от продукта Polyspace, используйте пользовательский интерфейс или интерфейс командной строки, чтобы задать порог. Для образца:

Идентифицируйте и уменьшайте сложность программного обеспечения

Идентифицируйте сложность программного обеспечения путем выполнения анализа Bug Finder

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

Пороги указывают на приемлемый уровень сложности программного обеспечения. Чтобы идентифицировать проблемы в коде, которые могут привести к более высокому уровню сложности, после настройки проверки сложности программного обеспечения запустите анализ 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)));
}
В этом коде ни одна из программных шашек сложности не поднята, что указывает на то, что вы снизили сложность этого кода до приемлемого уровня. Чтобы уменьшить сложность программного обеспечения:

  1. Документируйте код с достаточными комментариями.

  2. Сломать Большую сложную задачу, выполняемую AppxIndex в меньшие и более простые задачи, которые затем делегируются отдельным функциям, таким как CalculateU, CalculateV и CalculateMid. Функция power теперь вызывается реже. Если вы позже реализуете другую функцию, чтобы вычислить степень и хотите использовать новую функцию вместо текущей, вы должны сделать меньше замен.

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

Для получения дополнительной информации об адресации проверки сложности программного обеспечения см. документацию средства проверки.

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

Похожие темы