Крім свого прямого призначення в практичному відношенні метрики довжини програми (3) і довжини реалізації (2) можна використовувати для виявлення недосконалостей програмування. Якщо розрахунки довжини програми і довжини реалізації відрізняються більш ніж на десять відсотків, то це свідчить про можливу наявність у програмі наступних шести класів недосконалостей:
Наявність послідовності доповнюють один одного операторів до одного і того ж операнду, наприклад, А + C-А.
Наявність неоднозначних операндів, наприклад, A = D і A = С.
Наявність синонімічних операндів, наприклад, А = В і Т = В.
Наявність загальних подвираженій, наприклад (А + В) С + D (А + В).
Непотрібне присвоювання, наприклад С = А + В, якщо змінна С використовується в програмі тільки один раз.
Наявність виразів, які не представлені в згорнутому вигляді як твір множників, наприклад XX + 2XY + YY не представлено як (X + Y) (X + Y).
Довжину реалізації N (2) можна використовувати для прогнозу числа фактичних машинних команд P за допомогою виразу
або більш грубо, з допомогою нерівності
Рівняння роботи (9) можна використовувати для оцінки економічної ефективності використання тієї чи іншої мови програмування. Відносне скорочення роботи з програмування в залежності від рівня мови використовують як показник ефективності впровадження мови програмування в виробничу практику.
Рівень програми 0L1 можна використовувати для оцінки складності варіантів реалізації заданого алгоритму D (чим менше витрат пам'яті, тим складніше варіант програми):
Відзначимо, що рівень програми грає подвійну роль в оцінці труднощі або легкості її розуміння. Спеціаліст, який добре знає мову програмування, зрозуміє програму тим швидше, чим менше її обсяг, тобто вище рівень. Але для людини, менш розбирається в програмуванні, потрібен більший обсяг і менший рівень. Встановлено, що для будь-якого алгоритму, описаного різними мовами, зі збільшенням обсягу програми V рівень програми L зменшується в тій же пропорції. Тому твір рівня програми на обсяг є постійною величиною, рівною потенційному обсягу реалізації даного алгоритму.
L V = V * = const. (20)
Разом з тим, якщо мова не змінюється, а змінюється тільки алгоритм, то для будь-якої мови твір потенційного обсягу на рівень програми залишається постійною величиною, рівною рівню мови [14]
L V = = const. (21)
1.3.6 Метрики цикломатическая складності по Мак-Кейб
Показник цикломатическая складності є одним з найбільш поширених показників оцінки складності програмних проектів. Даний показник був розроблений вченим Мак-Кейб в 1976 р відноситься до групи показників оцінки складності потоку керування програмою і обчислюється на основі графа керуючої логіки програми (control flow graph). Даний граф будується в вигляді орієнтованого графа, в якому обчислювальні оператори або вираження представляються у вигляді вузлів, а передача управління між вузлами - у вигляді дуг.
Показник цикломатическая складності дозволяє не тільки провести оцінку трудомісткості реалізації окремих елементів програмного проекту і скорегувати загальні показники оцінки тривалості і вартості проекту, але і оцінити пов'язані ризики і прийняти необхідні управлінські рішення.
Для обчислення цикломатическая числа Мак-Кейба (G) застосовується формула:
де m - число дуг орієнтованого графа G;
n - число вершин;
p - число компонентів зв'язності графа.
Мак-Кейб використовує наступну теорему: в сильно пов'язаному графі G цикломатичне число дорівнює максимальному числу лінійно-незалежних циклів.
Застосовуючи цю теорему, число компонентів зв'язності графа можна розглядати як кількість дуг, які необхідно додати для перетворення графа в сильно зв'язний. Сильно зв'язковим називається граф, будь-які дві вершини якого взаємно досяжні. Для графів коректних програм, т. Е. Графів, які не мають недосяжних від точки входу ділянок і "висячих" точок входу і виходу, сильно зв'язний граф, як правило, виходить шляхом замикання дугою вершини, що позначає кінець програми, на вершину, що позначає точку входу в цю програму.
Спрощена формула обчислення цикломатическая складності розподілена так:
Як правило, при обчисленні цикломатическая складності логічні оператори не враховуються.
У процесі автоматизованого обчислення показника цикломатическая складності, як правило, застосовується спрощений підхід, відповідно до якого побудова графа не здійснюється, а обчислення показника проводиться на підставі підрахунку числа операторів керуючої логіки (if, switch і т.д.) і можливої кількості шляхів виконання програми.
Загальний підхід полягає в оцінці складності програми за допомогою обчислення числа лінійно-незалежних шляхів, цикломатическая складності (G), а також управління розміром програм за допомогою обмеження (G) і використання (G) як основи для методології тестування. Мак-Кейб виявив, що розумної верхньою межею для цикломатическая складності є 10. Якщо програмісти переступають цю межу, їм слід або переписати програму, або розбити її на модулі.
У фізичному сенсі цикломатичне число для кожної дуги m = (v, u) | mM графа управління перша вершина (v) є вихідною, а друга (u) - кінцевої. Шлях від однієї вершини до іншої вершини графа, якщо він складається більш ніж з однієї дуги, описують послідовністю вершин відповідних дуг (v, а, ..., u) так, що вихідна вершина буде першою в перерахуванні, а кінцева - останньої. Контур - це площина, обмежена циклічним шляхом, в якому початкова і кінцева вершина графа збігаються. Кожному контуру відповідає обмежує його шлях, що веде з початкової вершини графа в кінцеву.
Цикломатичне число визначає кількість незалежних контурів в повнозв'язну графі і, як наслідок, кількість різних шляхів, що ведуть з початкової вершини в кінцеву.
У практичному аспекті цикломатичне число є мірою складності програми і визначає кількість тестів, достатніх для тестування за критерієм покриття всіх гілок програми.
При оцінці складності програми з використанням цикломатическая числа Мак-Кейба діє наступне правило: якщо цикломатичне число більше десяти, програма має зайвої складністю і її слід розбити на складові частини (незалежні модулі або підпрограми) з меншим значенням цикломатическая числа.
Показник цикломатическая складності може бути розрахований для модуля, методу та інших структурних одиниць програми.
Обчислення метрики в ході реалізації проекту (а при детальному проектуванні воно можливо ще на цьому етапі, не чекаючи стадії кодування) дозволяє своєчасно визначити найбільш складні, що супроводжуються високими ризиками, структурні одиниці та вжити заходів щодо усунення ризиків за рахунок внесення коректив.
Розглянемо приклад. Нехай є програма, яка зчитує з вхідного потоку символи до тих пір, поки не буде виявлений символ «#». Текст програми на мові Паскаль представлений на рис 6. Відповідний граф управління програми показаний на рис 7.
Рис 6. Програма введення даних
Для представлення програми у вигляді графа потрібні певні угоди про те, що вважати вузлом графа, так як синтаксис операторів в мовах програмування досить різноманітний. При цьому зазвичай враховують тільки виконані оператори, виключаючи оператори опису даних. Бажано підібрати такі синтаксичні форми операторів, які найбільшою мірою підходять для відображення вузлом графа. Лінійні ділянки програми можна замінити одним вузлом графа. В цьому відношенні використання схем алгоритмів або опис програм на псевдокоді може виявитися навіть більш кращою формою опису програми, ніж текст на мові програмування. У будь-якому випадку бажано перетворити оператори циклу в еквівалентну послідовність операторів розгалуження, додавши, при необхідності, оператори підсумовування (лічильники) числа повторень циклу з «верхнім» або «нижнім» закінченням.
Рис 7. Граф управління програми введення даних
Рис 8. Перетворення графа управління програми введення даних в повнозв'язну граф
Визначимо цикломатичне число МакКейб для графа управління програми, зображеного на рис 7. Кількість ребер графа дорівнює п'яти, кількість вершин теж дорівнює п'яти, тому цикломатичне число дорівнює:
Програма організації введення даних, що має граф управління з цикломатическая числом, рівним 2, не володіє зайвої складністю і для її тестування досить підібрати два тести, що покривають гілки (а, b, с) і (а, u) (рис 4). Зауважимо, що вершини v і а графа управління програми можна об'єднати, що не приведе до зміни цикломатическая числа. Цикломатичне число залежить тільки від кількості керуючих операторів, що містять умовні вирази (предикати). При цьому складність предиката не враховується. Якщо в операторі циклу while програми організації введення даних (рис 4) ускладнити умовний вираз (предикат), змінивши заголовок
while (s<>'#') На while (s<>'#' Or s<>'*') Граф управління і цикломатичне число залишаться колишніми.
Якщо програма містить тільки оператори розгалуження (без операторів вибору і перемикання), цикломатичне число можна визначити, використовуючи вираз
де u - кількість операторів розгалуження.
При необхідності оператори вибору або перемикання з n гілками, можна розглядати як n операторів розгалуження.
До переваг заходи відносять простоту її обчислення і повторюваність результату, а також наочність і змістовність інтерпретації. Як недоліки можна відзначити: нечутливість до розміру ПО, нечутливість до зміни структури ПО, відсутність кореляції зі структурованістю ПО, відсутність відмінності між конструкціями Розвилка і Цикл, відсутність чутливості до вкладеності циклів. Недоліки цикломатическая заходи призвело до появи її модифікацій, а також принципово інших заходів складності.
Модифікації показника цикломатическая складності:
«Модифікована» цикломатическая складність - розглядає не кожне розгалуження оператора множинного вибору (switch), а весь оператор як єдине ціле.
«Сувора» цикломатическая складність - включає логічні оператори.
«Спрощена» обчислення цикломатическая складності - передбачає обчислення не на основі графа, а на основі підрахунку керуючих операторів.
«Актуальна» складність - визначається як число незалежних шляхів, які проходить програма при тестуванні;
метрика складності глобальних даних - обчислюється як цикломатическая складність модуля і збільшується на кількість взаємозв'язків з глобальними даними.