Тема.
Вимоги до якості програмного забезпечення
План
1. Фактори впливу.
2. Гарантоздатність. Рівні
цілісності програмного забезпечення.
3. Процеси підвищення
якості.
4. Метрики якості.
1. Фактори впливу
На планування, управління
впливають різні чинники, серед яких:
Ø область застосування системи, в якій буде
працювати програмне забезпечення (критичне для безпеки <людей>, критичне
для бізнесу і т.п.);
Ø системні та програмні вимоги;
Ø які
компоненти використовуються в системі — комерційні (зовнішні) або стандартні
(внутрішні);
Ø які
стандарти програмної інженерії застосовані в заданому контексті;
Ø які
методи і програмні інструменти застосовуються для розробки та супроводження, а
також для забезпечення якості і вдосконалення (продукту і процесів);
Ø бюджет, персонал, організація проектної
діяльності, плани і розклади для всіх процесів;
Ø хто
цільові користувачі і яке призначення системи;
Ø рівень
цілісності системи.
Інформація про ці фактори впливає на те, як саме будуть організовані і
задокументовані процеси SQM,
які SQM-роботи будуть відібрані (стандартизовані в
рамках проекту, команди, організаційної одиниці, організації), які необхідні
ресурси і які обмеження, що накладаються стосовно зусиль, що направляються на
забезпечення якості.
2.
Гарантоздатність. Рівні цілісності програмного забезпечення
Гарантоздатність — гарантія високої надійності, захищеності
від збоїв. У випадках, коли збій системи може призвести до вкрай тяжких
наслідків (такі системи іноді називають в англомовних джерелах «high confidence»
або «high integrity
system», до них іноді застосовують назву «системи підвищеної надійності», "високої доступності" і т.п.),
загальна (сукупна) гарантоздатність системи (як поєднання апаратної частини, програмного забезпечення і
людини) є головною і пріоритетною вимогою якості, по відношенню до основної
функціональності системи.
Гарантоздатність (dependability) програмного забезпечення включає такі характеристики, як:
ü захищеність від збоїв (fault-tolerance);
ü
безпека
використання (safety —
безпека в контексті прийнятного ризику для
здоров'я людей, бізнесу, майна тощо);
ü
інформаційна
безпека чи захищеність (security — захист інформації від несанкціонованих
операцій, включаючи доступ на читання, а також гарантія доступності інформації
для авторизованих користувачів, в обсязі заданих для них прав);
ü
зручність і
простота використання (usability);
ü
надійність
(reliability).
Рівень цілісності програмного забезпечення
визначається на підставі можливих наслідків збою програмного забезпечення та
можливість виникнення такого збою. Коли важливі різні аспекти безпеки
(застосування та інформаційної безпеки), під час розробки планів
робіт в області ідентифікації можливих осередків аварій можуть
використовуватися техніки аналізу небезпек (у контексті безпеки використання, safety) та
аналізу загроз (в інформаційній безпеці, security).
Історія збоїв аналогічних систем може також допомогти в ідентифікації
найбільш корисних технік, спрямованих на виявлення збоїв і всебічної оцінки
якості програмного забезпечення.
Якість програмного забезпечення може підвищуватися за рахунок ітерактивного процесу постійного поліпшення. Це
вимагає контролю, координації та зворотного зв'язку в процесі управління
багатьма одночасно виконуваними процесами:
Ø життєвого циклу;
Ø виявлення, усунення та запобігання збоїв;
Ø дефектів;
Ø поліпшення якості.
До програмної інженерії застосовні теорії та концепції, що лежать в
основі вдосконалення якості. Наприклад, запобігання та рання діагностика
помилок, постійне вдосконалення (continuous improvement) та увага до вимог замовника (customer focus), що
складають принцип "building in quality".
Ці концепції грунтуються на роботах експертів
з якості, які прийшли до думки, що якість продукту прямо пов'язана з якістю використовуваних для його створення
процесів.
Що таке хороша програма і чим вона відрізняється від поганої? Сьогодні
таке питання зазвичай трактується в плані оцінки якості програми кінцевим
користувачем. Але насправді він актуальний і для самих розробників ПЗ, правда,
при цьому вони в першу чергу мають на увазі не споживчі властивості програми, а
якість її коду.
У цілому вже давно загальновизнано, що поняття
"поганий / хороший код" пов'язано навіть не стільки з ефективністю
використання обчислювальних ресурсів (швидкодією програми, обсягом займаної оперативної
пам'яті тощо), скільки із завданнями наладки та модифікації ПЗ (на етапах як
власне розробки, так і супроводу). У цій ситуації якість коду визначається такими показниками, як правильне
розбиття програми на модулі, обмеження у використанні потенційно ризикованих
мовних конструкцій, наочне оформлення вихідного коду.
Але навіть визначивши склад ключових показників (метрик) якості коду,
практично неможливо створити універсальні критерії, що дозволяють вважати
програму "поганою" або "хорошою". У будь-якому випадку така оцінка носить дуже
суб'єктивний характер, і навіть для одного програміста вона буде варіюватися
залежно від типу проекту. Тому існуючі інструменти визначення метрик коду (code metrics) в основному обмежуються обчисленням відповідних значень, інтерпретація
яких повністю покладається на людину.
Ось за
якими метриками коду можна стежити вже зараз:
Ø індекс експлуатаційної надійності (MaintainabilityIndex, MI) —
комплексний показник якості коду (від 0 до 100 — чим вище, тим краще), методика його визначення
розроблена фахівцями Carnegie Mellon Software Engineering Institute;
Ø циклічна складність (Cyclomatic Complexity, CC)
— показник,
що характеризує число гілок в програмному коді та обчислюється шляхом
підрахунку операторів циклу, умовного переходу і перемикань;
Ø глибина успадкування (Depth of
Inheritance) — характеризує довжину
ланцюжків спадкування в програмному коді;
Ø зчеплення класів (Class Coupling)
— відображає ступінь
залежності класів між собою (в тому
числі наявність спільних даних, об'єктів тощо);
Ø число рядків коду: чим більше рядків, тим складніша програма.
Звичайно, для більш детального аналізу якості коду бажано
використовувати більше показників, які можна визначати за допомогою засобів
третіх фірм (є чимало і безкоштовних продуктів). Але, як правило, більш широкий
спектр характеристик потрібно тільки в навчальних цілях і не застосовується
розробниками на практиці.
4.
Метрики якості
Метрика програмного
забезпечення (англ. software metric)
— це міра, яка дозволяє
отримати числове значення деякої властивості ПЗ або його специфікацій.
У загальному випадку застосування метрик дозволяє
керівникам проектів і підприємств вивчити складність розробленого або навіть
розробляється проекту, оцінити обсяг робіт, стилістику розроблення програми і
зусилля, витрачені кожним розробником для реалізації того чи іншого рішення.
Однак метрики можуть служити лише рекомендаційними характеристиками,
ними не можна повністю керуватися, тому що під час розробки ПЗ
програмісти, прагнучи мінімізувати або максимізувати ту чи іншу міру для своєї
програми, можуть вдаватися до хитрощів аж до зниження
ефективності роботи програми. Крім того, якщо, наприклад, програміст написав
малу кількість рядків коду або вніс невелике
число структурних змін, це зовсім не означає, що він нічого не робив, а може
означати, що дефект програми було дуже складно відшукати. Остання проблема,
однак, частково може бути вирішена під час використання метрик
складності, тому що в більш складній програмі помилку знайти складніше.
Метрики складності програм прийнято поділяти на три основні групи:
Ø
метрики розміру програм;
Ø
метрики складності потоку управління програм;
Ø
метрики складності потоку даних програм.
Метрики першої групи базуються на визначенні кількісних характеристик,
пов'язаних з розміром програми, і відрізняються відносною простотою. До
найбільш відомих метрика цієї групи відносяться кількість операторів програми,
кількість рядків вихідного тексту, набір метрик Холстеда. Метрики цієї групи орієнтовані на аналіз
вихідного тексту програм. Тому вони можуть використовуватися для оцінки
складності проміжних продуктів розробки.
Метрики другої групи базуються на аналізі керуючого графа програми.
Представником цієї групи є метрика Маккейба. Керуючий граф (блок-схема програми), який використовують метрики даної
групи, може бути побудований на основі алгоритмів модулів. Тому метрики другої
групи можуть застосовуватися для оцінки складності проміжних продуктів
розробки.
Метрики третьої групи базуються на оцінці використання, конфігурації і розміщення
даних у програмі. У першу чергу це стосується глобальних змінних. До цієї групи
відносяться метрики Чепіна.
Loc- оцінки якості
Розмірно—орієнтовані метрики прямо вимірюють програмний продукт і процес
його розробки. Грунтуються такі метрики на LОС-оцінках.
Цей вид метрик побічно вимірює програмний продукт і процес його
розробки. Замість підрахунку LOC-оцінок
при цьому розглядається не розмір, а функціональність
або корисність продукту. Найбільше поширення в практиці створення програмного
забезпечення отримали розмірно-орієнтовані
метрики.
В організаціях, зайнятих розробкою програмної продукції для кожного
проекту прийнято реєструвати наступні показники:
Ø загальні трудовитрати (в людино-місяцях, людино - годинах);
Ø обсяг
програми (в тисячі рядках вихідного коду-LOC);
Ø вартість розробки;
Ø обсяг
документації;
Ø помилки, виявлені протягом року експлуатації;
Ø кількість людей, які працювали над виробом;
Ø термін
розробки.
На основі цих даних зазвичай підраховуються прості метрики для оцінки
продуктивності праці (LOC людино-місяць) і
якості виробу. Ці метрики не універсальні і спірні, особливо це відноситься до
такого показника як LOC, який суттєво залежить від мови програмування.
Приклад з життя:
На наш погляд оцінка за кількістю рядків у
коді тягне за собою спокусу написати більше рядків, щоб взяти побільше грошей. Зрозуміло, про
оптимізацію в такому продукті ніхто вже думати не стане.
Кількість рядків вихідного коду (Lines of
Code - LOC,
Source Lines of
Code - SLOC) є
найбільш простим і розповсюдженим способом оцінки обсягу робіт за проектом.
Спочатку даний показник виник як спосіб оцінки обсягу роботи за
проектом, в якому застосовувалися мови програмування, що володіють досить
простою структурою: «один рядок коду = одна команда мови». Також давно відомо,
що одну й ту ж функціональність можна написати різною кількістю рядків, а якщо
візьмемо мову високого рівня (С++, Java),
то можливо і в одному рядку написати
функціонал 5-6 рядків — це не проблема. І це було б
півбіди: сучасні засоби програмування самі генерують тисячі рядків коду на дріб'язкову операцію. Тому метод LOC є тільки оціночним методом (який треба брати
до відома, але не спиратися в оцінках) і ніяк не обов'язковим. Залежно від того, яким чином враховується
подібний код, виділяють два основні показники SLOC:
Ø кількість «фізичних» рядків коду — SLOC (використовуються
абревіатури LOC, SLOC, KLOC,
KSLOC, DSLOC) —
визначається як загальне число рядків вихідного коду, включаючи коментарі і
порожні рядки (при вимірюванні показника на кількість порожніх рядків, як правило, вводиться обмеження —— при підрахунку враховується кількість порожніх
рядків, що не перевищує 25% загального числа рядків у вимірювальному блоці коду);
Ø Кількість «логічних» рядків коду — SLOC (використовуються
абревіатури LSI, DSI, KDSI,
де «SI» — source instructions)
— визначається як кількість команд і залежить
від мови програмування. У тому випадку, якщо мова не допускає розміщення
кількох команд в одному рядку, то кількість «логічних» SLOC буде відповідати числу «фізичних», за
винятком числа порожніх рядків і рядків коментарів. У тому випадку, якщо мова
програмування підтримує розміщення кількох команд в одному рядку, то один фізичний рядок
повинен бути врахований як кілька логічних, якщо вона містить більше
однієї команди мови.
Для метрики SLOC існує велике число похідних, покликаних
отримати окремі показники проекту, основними серед яких є:
Ø кількість порожніх рядків;
Ø число
рядків, що містять коментарі;
Ø відсоток коментарів (відношення рядків коду до
рядків коментаря, похідна метрика стилістики);
Ø середнє число рядків для функцій (класів, файлів);
Ø середнє число рядків, що містять вихідний код
для функцій (класів, файлів);
Ø середнє число рядків для модулів.
Недоліки SLOC
Потенційні
недоліки SLOC, на які орієнтована критика:
Ø Некрасиво і неправильно зводити оцінку роботи
людини до декількох числових параметрів і по них судити про продуктивність. Менеджер
може призначити найбільш талановитих програмістів на складну ділянку роботи; це означає, що розробка цієї
ділянки займе найбільше часу і породить найбільшу кількість помилок,
через складність завдання. Не знаючи про ці труднощі, інший менеджер з
отриманими показниками може вирішити, що програміст зробив свою роботу погано.
Ø Метрика не враховує досвід співробітників та
їх інші якості.
Ø Спотворення: процес вимірювання може бути
спотворений за рахунок того, що співробітники знають про вимірювання показників і прагнуть оптимізувати ці показники, а не
свою роботу. Наприклад, якщо кількість рядків вихідного коду є важливим
показником, то програмісти будуть прагнути писати якомога більше рядків і не
будуть використовувати способи спрощення коду, що скорочують кількість рядків.
Ø Неточність: немає метрик, які були б одночасно і значущі і
досить точні. Кількість рядків коду — це просто кількість рядків, цей показник
не дає уявлення про складність вирішуваної проблеми. Аналіз функціональних
точок був розроблений з метою кращого вимірювання складності коду і
специфікації, але він використовує особисті оцінки вимірювального, тому різні
люди отримають різні результати.
І головне пам'ятати: метрика SLOC не відображає трудомісткості за створення програми.
Метрики стилістики й зрозумілості програм
Іноді важливо не просто порахувати кількість рядків
коментарів в коді і просто співвіднести з логічними рядками коду, а дізнатися
щільність коментарів. Тобто код
спочатку був документований добре, потім — погано.
Метрики
складності
Крім показників оцінки обсягу робіт за проектом дуже важливими для
отримання об'єктивних оцінок є показники оцінки його складності. Як правило,
дані показники не можуть бути обчислені на самих ранніх стадіях роботи над
проектом, оскільки вимагають, як мінімум, детального проектування. Однак ці
показники дуже важливі для отримання прогнозних оцінок тривалості і вартості
проекту, оскільки безпосередньо визначають його трудомісткість.
Метрики Опис
Зважена насиченість
класу 1 (Weighted
Methods Per Class
(WMC). Відображає відносну міру
складності класу на основі циклічної складності кожного його методу. Клас з
більш складними методами і великою кількістю методів вважається більш складним.
Згідно обчислень метрики батьківські класи не враховуються.
Зважена насиченість
класу 2 (Weighted
Methods Per Class
(WMC2)). Міра складності класу,
заснована на тому, що клас з великою кількістю методів, є більш складним, і що
метод з великою кількістю параметрів також є більш складним. Згідно обчислень
метрики батьківські класи не враховуються.
Глибина дерева
успадкування (Depth of
inheritance tree). Довжина
найдовшого шляху спадкоємства, що закінчується на даному модулі. Чим глибше
дерево успадкування модуля, тим може опинитися складніше передбачити його
поведінку. З іншого боку, збільшення глибини дає більший потенціал повторного
використання даним модулем поведінки, визначеного для класів-предків.
Кількість нащадків (Number of
children). Число модулів, безпосередньо успадковують
даний модуль. Більші значення цієї метрики вказують на широкі можливості повторного
використання при цьому занадто велике значення може свідчити про погано
вибраної абстракції.
Зв'язність об'єктів (Coupling between objects).
Кількість модулів, пов'язаних з даним модулем
в ролі клієнта або постачальника. Надмірна зв'язність говорить про слабкість
модульної інкапсуляції і може перешкоджати повторному використанню коду.
Відгук на клас (Response For Class).
Кількість методів, які
можуть викликатися екземплярами класу, обчислюється як сума кількості локальних
методів, так і кількості вилучених методів.
Метрики Холстеда
Метрика Холстед відноситься до обчислювальної метрики, на підставі аналізу числа рядків і синтаксичних елементів початкового коду програми.
Основу метрики Холстед складають чотири вимірювані характеристики програми:
Ø
NUOprtr (Number of Unique Operators) — число унікальних
операторів програми, включаючи символи—роздільники, імена процедур і знаки
операцій (словник операторів);
Ø
NUOprnd
(Number of Unique
Operands) — число унікальних операндів програми (словник
операндів);
Ø
Noprtr
(Number of Operators)
— загальна кількість операторів в програмі;
Ø
Noprnd
(Number of Operands)
— загальна кількість операндів в програмі.
Метрики циклічної складності за Мак-Кейбом
Показник
циклічної складності є одним з найпоширеніших показників оцінки складності
програмних проектів. Даний показник був розроблений вченим Мак—Кейбом в 1976 р., належить
до групи показників оцінки складності потоку управління програмою і
обчислюється на основі графу керуючої
логіки програми (control
flow graph). Даний
граф будується у вигляді орієнтованого графу, в якому обчислювальні оператори або вирази
позначаються у вигляді вузлів, а передача управління між
вузлами — у вигляді дуг.
Показник
циклічної складності дозволяє не тільки зробити оцінку трудомісткості реалізації окремих
елементів програмного проекту і скорегувати загальні показники оцінки тривалості і вартості проекту,
а й оцінити пов'язані ризики і прийняти необхідні управлінські рішення.
Спрощена формула обчислення циклічної складності відображається наступним чином:
C = e — n + 2,
де e — число ребер, а n — число вузлів на графі керуючої логіки.
Як правило, згідно обчислень циклічної складності логічні оператори не
враховуються.
У процесі автоматизованого обчислення показника циклічної складності, як
правило, застосовується спрощений підхід, відповідно до якого побудова графа не
здійснюється, а обчислення показника проводиться на підставі підрахунку
кількості операторів керуючої логіки (if, switch
і т.д.) і можливої кількості шляхів виконання
програми.
Цикломатичне число Мак-Кейба показує необхідну кількість проходів
для покриття всіх контурів сильнозв’язаного графу або кількості тестових
прогонів програми, необхідних для вичерпного тестування за принципом «працює
кожна гілка». Показник циклічної складності може бути розрахований для модуля,
методу та інших структурних одиниць програми.
Існує значна кількість модифікацій показника
циклічної складності.
Ø «Модифікована» цикломатична складність — розглядає не кожне розгалуження
оператора множинного вибору (switch), а весь оператор як єдине ціле.
Ø «Строга» цикломатична складність — включає логічні оператори.
Ø «Спрощена» обчисленість циклічної складності — передбачає обчислення
не на основі графа, а на основі підрахунку керуючих операторів.
Існує кілька її модифікацій. Розглянемо більш простий, а з точки зору
практичного використання — досить ефективний варіант цієї метрики.
Суть методу полягає в оцінці інформаційної міцності окремо взятого
програмного модуля за допомогою аналізу характеру використання змінних зі
списку вводу-виводу.
Всі безліч змінних, що складають список вводу-виводу, розбивається на чотири функціональні
групи.
1. Безліч
«Р» — що вводяться змінні для розрахунків та для забезпечення виведення.
Прикладом може служити змінна, що
використовується в програмах лексичного аналізатора, яке містить рядок вихідного тексту програми,
тобто сама змінна не модифікується, а лише
містить вихідну інформацію.
2. Безліч
«М» — модифікуються або створювані усередині програми змінні.
3. Безліч
«С» — змінні, що беруть участь в управлінні роботою програмного модуля (керуючі
змінні).
4. Безліч
«Т» — не використовуються в програмі ( "паразитні") змінні. Оскільки
кожна змінна може виконувати одночасно декілька функцій, необхідно враховувати
її в кожній відповідній функціональній групі.
Далі вводиться
значення метрики Чепіна:
0 = а1Р + а2М
+ аЗС + а4Т,
де а1, а2, аЗ,
а4 — вагові коефіцієнти.
Вагові коефіцієнти використані для відображення різного впливу на
складність програми кожної функціональної групи. На думку автора метрики
найбільшу вагу, що дорівнює трьом, має функціональна група С, так як вона
впливає на потік управління програми. Вагові коефіцієнти інших груп
розподіляються таким чином: а1 = 1; а2 = 2; а4 = 0.5. Ваговий коефіцієнт групи
Т не дорівнює нулю, оскільки "паразитні" змінні не збільшують
складності потоку даних програми, але іноді ускладнюють її розуміння. З
урахуванням вагових коефіцієнтів вираз набуде вигляду:
Попередня оцінка якості на основі
статистичних методів в залежності від етапу розробки програми.
При використанні інтегрованих інструментальних
засобів у компаній, що розробляють типові рішення (під цю категорію потрапляють
так звані «інхаузери» — компанії, що займаються обслуговуванням основного
бізнесу) з'являється можливість будувати прогнози складності програм,
грунтуючись на зібраній статистиці. Статистичний метод добре підходить для вирішення подібних типових завдань
і практично не підходить для прогнозу унікальних проектів. У випадку унікальних
проектів застосовуються інші підходи, обговорення яких знаходиться за рамками
даного матеріалу.
Типові завдання падають на відділи розробки з
бізнесу, бо попередня оцінка складності могла б сильно спростити завдання
планування та управління, тим більше, що є накопичена база по проектах, в якій
збережено не лише остаточні результати, а й всі початкові та проміжні.
Виділимо типові етапи в розробці програм:
Ø розробка специфікації вимог до програми;
Ø визначення архітектури;
Ø опрацювання модульної структури програми,
розробка інтерфейсів між модулями;
Ø опрацювання алгоритмів;
Ø розробка коду і тестування.
Тепер спробуємо розглянути ряд метрик, що часто використовуються для попередньої
оцінки на перших двох етапах.
Попередня оцінка складності програми на етапі
розробки специфікацій вимог до програми. Для оцінки за результатами роботи даного етапу може бути використана
метрика прогнозованого числа операторів Nпрогн програми:
Nпрогн = NF
* Код
де: NF
— кількість функцій чи
вимог у специфікації програми, що розробляється;
Код — одиничне значення кількості операторів (середня кількість
операторів, що припадають на одну середню функцію або вимогу).
Значення Код — статистичне.
Питання для самоконтролю:
1. Навести рівні цілісності программного
забезпечення.
2. Проаналізувати процес підвищення якості (Quality Improvement).
3. Надати визначення поняттю метрики як основи
вимірювання.
4. Оцінка якості коду в програмі.
5. Описати призначення Loc-оцінок
якості, визначити їх роль при забезпеченні контролю якості програмних
продуктів.
6. Метрика стилістики і зрозумілості програм.
7. Проаналізувати метрики Холстеда, визначити їх роль при
забезпеченні контролю за якістю програмного забезпечення.
8. Метрики циклічної складності за Мак-Кейбом.
9. Метрики Чепіна.
10. Попередня оцінка якості на основі
статистичних методів в залежності від етапу розробки програми.
11. Попередня оцінка складності програми на етапі
розробки специфікацій вимог до програми.