Назад до блогу
6 хв читання

Нефункціональні вимоги: чому про них має думати кожен інженер

Сьогодні поговоримо про важливі відмінності між функціональними та нефункціональними вимогами і про те, чому нефункціональні вимоги мають хвилювати кожного технічного спеціаліста — від архітектора до розробника.

Функціональні та нефункціональні вимоги

Мабуть, кожен складний програмний продукт — це результат реалізації функціональних і нефункціональних вимог. Нефункціональні вимоги іноді ще називають міжфункціональними (cross-functional) або неповедінковими (non-behavioral).

Щоб відчути різницю між ними, уявімо, що ми розробники, які збираються спроєктувати й реалізувати Instagram з нуля. Ось як можуть виглядати деякі високорівневі функціональні вимоги:

  • користувачі можуть завантажувати фото;
  • користувачі можуть підписуватися на інших користувачів;
  • користувач може надсилати приватні повідомлення іншому користувачу;
  • користувачі бачать стрічку новин (news feed) із фото інших користувачів.

А ось кілька можливих нефункціональних вимог:

  • стрічка новин формується в середньому за 500 мс, а для 99% запитів (p99) — не довше ніж за 1 с;
  • фото, які завантажують користувачі, ніколи не губляться (довговічність даних, durability);
  • доступність (availability) системи — 99,99% часу.

Як видно з прикладу Instagram, функціональні вимоги описують, що система має робити, а нефункціональні — як вона має при цьому поводитися.

Інші важливі відмінності між функціональними та нефункціональними вимогами:

  • Система може працювати, навіть якщо реалізовано лише функціональні вимоги. Простим продуктам чи PoC (proof of concept) нефункціональні вимоги часто взагалі не важливі. Натомість нефункціональні вимоги неможливо реалізувати без функціональних.
  • Про функціональні вимоги легко домовитися, на відміну від нефункціональних. Наприклад, легко погодитися, що користувач Instagram може завантажити фото (функціональна вимога). Але як швидко домовитися про відсоток доступності (нефункціональна вимога)? 99,99%? А чому не 99,95%?
  • Функціональні вимоги зазвичай документують як сценарії використання (use cases) або user stories, а нефункціональні — як атрибути якості (quality attributes).
  • За збір (elicitation) і документування функціональних вимог відповідають бізнес-аналітики. За нефункціональні — зазвичай архітектори програмного забезпечення, а частково також техліди й кожен розробник.
  • І найважливіша відмінність із технічного погляду: архітектуру визначають насамперед нефункціональні вимоги. Функціональні впливають на неї значно менше — їх можна реалізувати майже в будь-якій архітектурі.

Функціональні вимоги та архітектура

Згадаймо, мабуть, найпростішу можливу архітектуру застосунку — трирівневу (3-tier architecture):

Трирівнева архітектура: клієнт, бекенд із бізнес-логікою та база даних

Річ у тім, що навіть найпростіша трирівнева архітектура здатна реалізувати будь-яку кількість дуже складних функціональних вимог: усі функціональні вимоги Instagram можна реалізувати на трирівневій архітектурі. У базі даних потенційно будуть сотні таблиць, а кодова база може налічувати сотні тисяч рядків коду. Звісно, з появою нових функцій супровідність (maintainability) такої монолітної системи може погіршуватися.

Проте трирівнева архітектура успішно реалізує функціональні вимоги, якщо вона правильно структурована, а якість коду підтримується на належному рівні. Реалізація нових функцій здебільшого зводитиметься до створення нових таблиць у базі даних, розширення доменної моделі, написання нових бізнес-правил та іншого допоміжного коду.

Головний висновок: коли йдеться лише про реалізацію функціональних вимог, архітектура програмного забезпечення і system design не мають великого значення.

Просто, чи не так?

Нефункціональні вимоги та архітектура

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

Як уже згадувалося, трирівнева архітектура може успішно реалізувати всі функціональні вимоги замовника. Уявімо, що трирівневу систему вже реалізовано і вона працює в продакшні:

Instagram на трирівневій архітектурі в продакшні: монолітний бекенд і база даних із сотнями таблиць

Але тепер з’являється нова нефункціональна вимога, яку раніше не враховували: усі GET-ендпоінти мають відповідати в середньому за 500 мс, а для 99% запитів (p99) — не довше ніж за 1 с при 5000 одночасних користувачів.

Звісно, розробники можуть спробувати досягти цього, оптимізувавши запити до бази даних, додавши кешування в пам’яті (in-memory caching), зменшивши кількість алокацій у керованій купі (managed heap) тощо. Проте у великій монолітній системі таких кроків — і навіть горизонтального масштабування — може виявитися недостатньо.

Щоб виконати таку вимогу, може знадобитися перепроєктувати систему (а для системи в продакшні це може стати справжнім кошмаром). Наприклад, упровадити патерн CQRS на рівні архітектури — з окремо масштабованими сервісами читання, окремим екземпляром кешу та іншими складними речами:

Можливий редизайн із CQRS: окремі шляхи для команд і запитів, масштабовані сервіси читання, кеш та окрема модель для читання

Якщо такі нефункціональні вимоги, як продуктивність (performance), доступність (availability) чи надійність (reliability), повністю проґавити на етапах збору вимог і проєктування, систему, можливо, доведеться перебудовувати архітектурно. До того ж, навіть якщо всі нефункціональні вимоги зібрано якомога раніше, дуже важливо звертати увагу на цифри. Наприклад, системи з доступністю 99,9% і 99,95% можуть потребувати двох різних архітектур, а 99,95% обійдуться ще й у значно більші рахунки від хмарного провайдера.

Для орієнтиру — скільки простою допускає кожен рівень доступності:

ДоступністьПростій за рікЗа місяцьЗа день
99,9%≈ 8 год 46 хв≈ 43 хв 50 с≈ 1 хв 26 с
99,95%≈ 4 год 23 хв≈ 21 хв 55 с≈ 43 с
99,99%≈ 52 хв 36 с≈ 4 хв 23 с≈ 9 с

Тож варто ставити собі запитання:

  • Чи справді системі потрібна доступність 99,95%? Чим обґрунтоване це число? Чому 99,9% недостатньо?
  • Чи справді кожен GET-ендпоінт має відповідати за 500 мс? Чим обґрунтоване це число? Можливо, така вимога стосується лише одного ендпоінта?
  • …

Вчасно поставлені запитання — ці та інші — можуть заощадити команді багато зусиль, а клієнтам — гроші.

Чому розробникам варто думати про нефункціональні вимоги

Нефункціональні вимоги — турбота не лише архітекторів, а й техлідів і розробників.

Коли розробник бере в роботу story, нефункціональні вимоги там можуть узагалі не згадуватися.

Наприклад, story може стосуватися нового API-ендпоінта з новою бізнес-логікою і новими таблицями в базі даних. Якщо нефункціональну вимогу — скажімо, максимальний час відповіді API 300 мс — у story не згадано і ніхто її заздалегідь не уточнив, розробник може використати неефективні алгоритми, неоптимальну схему бази даних, обійтися без кешування тощо, аби лише виконати функціональні вимоги і якнайшвидше передати story в QA.

Згодом з’явиться ризик переробляти реалізацію, коли QA-інженер або замовник побачить реальний час відповіді. Тож одне запитання від розробника чи техліда, поставлене заздалегідь, — «Яким має бути середній і максимальний час відповіді цього API?» — допоможе уникнути подвійної роботи.

Ключові висновки

  • Функціональні вимоги можна реалізувати на простій архітектурі. Нові функціональні вимоги зазвичай не потребують змін в архітектурі системи.
  • Нефункціональні вимоги можуть суттєво впливати на архітектуру системи. Як архітектор, подбайте, щоб важливі нефункціональні вимоги було зібрано якомога раніше — до проєктування та реалізації системи.
  • Нефункціональні вимоги можуть суттєво впливати на дизайн окремого вебсервісу чи мікросервісу, на алгоритми, структури даних тощо. Як техлід або розробник, уточнюйте нефункціональні вимоги — продуктивність, масштабованість (scalability), пропускну здатність (throughput), інтероперабельність (interoperability) — до того, як братися за реалізацію story. Так ви уникнете можливих переробок у майбутньому.

Це переклад моєї англомовної статті «Why Missing Non-Functional Requirements Can Be a Disaster», опублікованої на Medium. Таблицю простоїв додано в українській версії.

ЩО ВИВЧАТИ ДАЛІ